//@category Vegvisir
import ghidra.app.script.GhidraScript;
import ghidra.program.model.address.Address;
import ghidra.program.model.symbol.*;

public class VegvisirXrefs extends GhidraScript {
    private static String q(String s){ if(s==null)return"null"; StringBuilder b=new StringBuilder("\""); for(int i=0;i<s.length();i++){char c=s.charAt(i); switch(c){case '\\':b.append("\\\\");break;case '"':b.append("\\\"");break;case '\n':b.append("\\n");break;case '\r':b.append("\\r");break;case '\t':b.append("\\t");break;default: if(c<0x20)b.append(String.format("\\u%04x",(int)c)); else b.append(c);}} return b.append('"').toString(); }
    private void appendRef(StringBuilder out, Reference r){ out.append("{"); out.append("\"from\": ").append(q(r.getFromAddress().toString())).append(", "); out.append("\"to\": ").append(q(r.getToAddress().toString())).append(", "); out.append("\"type\": ").append(q(r.getReferenceType().toString())).append(", "); out.append("\"source\": ").append(q(r.getSource().toString())); out.append("}"); }
    public void run() throws Exception { String[] args=getScriptArgs(); String addrS=args.length>0?args[0]:""; String dir=args.length>1?args[1]:"to"; int limit=args.length>2?Integer.parseInt(args[2]):200; Address a=currentProgram.getAddressFactory().getAddress(addrS); if(a==null){println("VEGVISIR_JSON:{\"ok\":false,\"error\":\"invalid address\"}");return;} ReferenceManager rm=currentProgram.getReferenceManager(); StringBuilder out=new StringBuilder(); out.append("{\n  \"ok\": true,\n  \"address\": ").append(q(a.toString())).append(",\n  \"direction\": ").append(q(dir)).append(",\n  \"xrefs\": [\n"); int total=0, emitted=0; if(dir.equals("from")){ Reference[] refs=rm.getReferencesFrom(a); total=refs.length; for(Reference r: refs){ if(emitted>=limit)continue; if(emitted>0)out.append(",\n"); out.append("    "); appendRef(out,r); emitted++; } } else { ReferenceIterator it=rm.getReferencesTo(a); while(it.hasNext()){ Reference r=it.next(); total++; if(emitted>=limit)continue; if(emitted>0)out.append(",\n"); out.append("    "); appendRef(out,r); emitted++; } } out.append("\n  ],\n  \"emitted\": ").append(emitted).append(",\n  \"total\": ").append(total).append("\n}"); println("VEGVISIR_JSON:"+out.toString()); }
}
