package s3.services.j2c;
import ovm.core.domain.DomainDirectory;
import ovm.core.domain.Type;
import ovm.core.repository.TypeName;
import ovm.core.services.format.CxxFormat;
import ovm.core.repository.UTF8Store;
import ovm.util.HTint2Object;
import ovm.util.SparseArrayList;
import s3.core.domain.S3Blueprint;
import ovm.core.domain.Method;
import s3.services.bootimage.JNIFormat;

public class J2cFormat extends CxxFormat {
    static final boolean KEEP_CACHE_STATS = J2cImageCompiler.KEEP_STATS;
    
    static private HTint2Object memoUTF = new HTint2Object();
    static private int memoUTFHits;
    static private SparseArrayList[] memoMethod;
    static private int memoMethodHits;

    static String getUTF(int idx) {
	String ret = (String) memoUTF.get(idx);
	if (ret == null) {
	    ret = UTF8Store._.getUtf8(idx).toString();
	    memoUTF.put(idx, ret);
	}
	if (KEEP_CACHE_STATS)
	    memoUTFHits++;
	return ret;
    }

    static public String format(Method m) {
	if (memoMethod == null) {
	    memoMethod =
		new SparseArrayList[DomainDirectory.maxContextID() + 1];
	    for (int i = 0; i < memoMethod.length; i++) {
		Type.Context ctx = DomainDirectory.getContext(i);
		if (ctx != null)
		    memoMethod[i] = new SparseArrayList();
	    }
	}
	int cid = m.getCID();
	int uid = m.getUID();
	String j2cName = (String) memoMethod[cid].get(uid);
	if (j2cName == null) {
	    int suffix = (m.getCID() << 16) + m.getUID();
	    Type.Compound t = m.getDeclaringType();
	    TypeName.Scalar n = t.getName().asScalar();
	    String bpName = getUTF(n.getShortNameIndex());
	    String mName = getUTF(m.getSelector().getNameIndex());
	    j2cName = (JNIFormat._.encode(bpName) + '_'
		       + JNIFormat._.encode(mName) + '_'
		       + suffix);
	    memoMethod[cid].set(uid, j2cName);
	}
	if (KEEP_CACHE_STATS)
	    memoMethodHits++;
	return j2cName;
    }

    static public String formatBP(S3Blueprint bp) {
	if (bp instanceof S3Blueprint.Primitive)
	    return ("bp_" + format(bp.getS3Domain())
		    + "_" + format(bp));
	else if (bp instanceof S3Blueprint.Array)
	    return "bp_" + format(bp).replace('<', 'O').replace('*', 'P').replace('>','C');
	else
	    return "bp_" + format(bp);
    }

    static public String formatShSt(S3Blueprint bp) {
	if (bp.isSharedState())
	    bp = (S3Blueprint) bp.getInstanceBlueprint();
	return "static_" + format(bp);
    }

    static {
	if (KEEP_CACHE_STATS)
	    new J2cImageCompiler.StatPrinter() {
		public void printStats() {
		    System.err.println("\nJ2cFormat caches:\n");
		    System.err.println("utf8 -> string mapping:");
		    System.err.println("\tValues Allocated: "
				       + memoUTF.keys().length);
		    System.err.println("\tHits:             "
				       + memoUTFHits);
		    System.err.println("Method names:");
		    System.err.println("\tSlots Allocated:  "
				       + memoMethod.length);
		    System.err.println("\tValues Allocated: "
				       + countNonNull(memoMethod));
		    System.err.println("\tHits:             "
				       + memoMethodHits);
		}
	    };
    }
}

    
