package xdc.services.spec;

public class Cat {

	static Session ses;
	static Unit unit;
	
	String code;
	int ptrCnt = 0;
	
	protected Cat( String code, int ptrCnt )
	{
		this.code = code;
		this.ptrCnt = ptrCnt;
	}
	
	interface Indexed {
		Cat mkBaseCat();
	}
	
	interface Obj {
		Cat mkMbrCat( String id );
	}
	
	static void bindUnit( Unit unit )
	{
		Cat.unit = unit;
		Cat.ses = unit.getSession();
	}
	
	String code() { return "?"; }

	public String getCode()
	{
		String res = "";
		for (int i = 0; i < this.ptrCnt; i++) {
			res += "*";
		}
		return res + code();
	}
	
	public int getPtrCnt() { return this.ptrCnt; }
	
	// Cat.Arr
	public static class Arr extends Cat implements Indexed
	{
		private Arr( String code, int ptrCnt ) { super(code, ptrCnt); }
		String code() { return "A!" + this.code; };
		public Cat mkBaseCat() { return Cat.fromCode(this.code); }
	}
	
	// Cat.Fxn
	public static class Fxn extends Cat
	{
		private Decl.Fxn fxnDecl;
		
		private Fxn( String code, int ptrCnt ) { this(code, ptrCnt, null); }
		private Fxn( String code, int ptrCnt, Decl.Fxn fxnDecl )
		{
			super(code, ptrCnt);
			this.fxnDecl = fxnDecl;
		}

		String code() { return "F!" + this.code; };
		public Decl.Fxn getDecl() { return this.fxnDecl; }
		Cat mkRetCat() { return (Cat.fromCode(this.code)); }
	}
	
	// Cat.Ins
	public static class Ins extends Cat implements Obj
	{
		private Ins( String code, int ptrCnt ) { super(code, ptrCnt); }
		String code() { return "I!" + this.code; }

		public Cat mkMbrCat( String id ) 
		{
			for (Unit u = Cat.ses.findUnit(this.code); u != null; u = u.getSuper()) {
				Decl d = Cat.ses.findDecl(u, id);
				if (d != null && d.isInst()) {
					return Cat.fromDecl(d);
				}
			}
			
			return null;
		}
	}
	
	// Cat.Map
	public static class Map extends Cat implements Indexed
	{
		private Map( String code, int ptrCnt ) { super(code, ptrCnt); }
		String code() { return "M!" + this.code; };
		public Cat mkBaseCat() { return Cat.fromCode(this.code); }
	}
	
	// Cat.Sca
	public static class Sca extends Cat
	{
		private Sca( String code, int ptrCnt ) { super(code, ptrCnt); }
		String code() { return this.code; };
	}

	// Cat.Str
	public static class Str extends Cat implements Obj
	{
		private String altName = null;
		
		private Str( String code, int ptrCnt )
		{
			super(code, ptrCnt);
			int k = code.indexOf('#');
			if (k != -1) {
				this.altName = this.code.substring(k + 1); 
				this.code = this.code.substring(0, k);
			}
		}

		String code() { return "S!" + this.code; }
		
		public Cat mkMbrCat( String id ) 
		{
			Decl d = Cat.ses.findDecl(this.code + '.' + id);
			if (d != null) {
				return Cat.fromDecl(d);
			}
			
			Decl str = Cat.ses.findDecl(this.code);
			if (str.overrides() != null) {
				return Cat.fromDecl(Cat.ses.findDecl(str.overrides().getQualName() + '.' + id));
			}
			
			return null;
		}
		
		public final String getAltName() { return this.altName; }
	}
	
	// Cat.Uni
	public static class Uni extends Cat implements Obj
	{
		private boolean isProxy = false;
		
		private Uni( String code, int ptrCnt ) { super(code, ptrCnt); }
		String code() { return "U!" + this.code; }

		public Cat mkMbrCat( String id ) 
		{
			if (id.equals("$used")) {
				return Cat.fromCode("b");
			}
			
			for (Unit u = Cat.ses.findUnit(this.code); u != null; u = u.getSuper()) {
				Decl d = Cat.ses.findDecl(u, id);
				if (d != null) {
					// TODO check for isInst || create
					return Cat.fromDecl(d);
				}
			}
			
			return null;
		}
		
		public final boolean isProxy() { return this.isProxy; }
		final void setProxy() { this.isProxy = true; }
	}
	
	// fromCode
	static Cat fromCode( String tc )
	{
		int pcnt = 0;
		
		for (int i = 0; i < tc.length(); i++) {
			switch (tc.charAt(i)) {
			case 'P':
				pcnt++;
				break;
			case 'A':
				return new Cat.Arr(tc.substring(i + 1), pcnt);
			case 'F':
				return new Cat.Fxn(tc.substring(i + 1), pcnt);
			case 'I':
				return new Cat.Ins(tc.substring(i + 2), pcnt);
			case 'M':
				return new Cat.Map(tc.substring(i + 1), pcnt);
			case 'S':
				return new Cat.Str(tc.substring(i + 2), pcnt);
			case 'U':
				return new Cat.Uni(tc.substring(i + 2), pcnt);
			case 'b':
			case 'e':
			case 'f':
			case 'n':
			case 'o':	// TODO instance support
			case 's':
			case 'v':
				return new Cat.Sca(tc, pcnt);
			default:
				return null;
			}
		}
		
		return null;
	}
	
	// fromDecl
	static Cat fromDecl( Decl d )
	{
		if (d instanceof Decl.Struct) {
			return new Cat.Str(d.getQualName(), 0);
		}

		if (d instanceof Decl.Fxn) {
			Decl.Fxn fxn = (Decl.Fxn)d;
			if (fxn.getType() instanceof Type.Creator) {
				return new Cat.Fxn("o", 0, fxn);
			}
			else {
				return new Cat.Fxn(Cat.recode(fxn.getType()), 0, fxn);
			}
		}
		
		if (d instanceof Decl.Signature) {
			return Cat.fromType(((Decl.Signature)d).getType());
		}
		
		if (d instanceof Decl.Imp) {
			return Cat.fromUnit(((Decl.Imp)d).getUnit());
		}
		
		if (d instanceof Decl.Proxy) {
			return Cat.fromProxy(((Decl.Proxy)d));
		}
		
		if (d instanceof Decl.EnumVal) {
			return new Cat.Sca("e", 0);
		}

		return null;
	}
	
	// fromProxy
	static Cat fromProxy( Decl.Proxy prx )
	{
		Cat.Uni res = new Cat.Uni(prx.getUnit().getSuper().getQualName(), 0);
		res.setProxy();
		return res;
	}
	
	// fromType
	static Cat fromType( Type t )
	{
		return Cat.fromCode(Cat.recode(t));
	}
	
	// fromUnit
	static Cat fromUnit( Unit u )
	{
		return new Cat.Uni(u.getQualName(), 0);
	}
	
	// recode
	static String recode( Type t )
	{
		t = t.raw();
		String tc = t.tcode();
		
		Ref r = t.tspec().getRef();

		if (tc.endsWith("E")) {
			return recodeStr(r, tc);
//			return recodeStr((Decl.Struct)(t.tspec().getRef().getNode()), tc);
		}
		
		if (tc.endsWith("S")) {
			return recodeStr(r, tc);
//			tc += "!" + t.tspec().getRef().getNode().getQualName();
		}
		
		if (tc.equals("o")) {
			if (r.getId().equals("Module")) {
				return "U!" + r.getScope();
			}
		}

		if (tc.endsWith("o")) {
			if (r.getId().equals("Instance")) {
				tc = tc.substring(0, tc.length() - 1) + "I!" + r.getScope();
			}
		}
		
		return tc;
	}
	
	// recodeStr
	static String recodeStr( Ref ref, String tc )
	{
		Node node = ref.getNode();
		Decl.Proxy prx = ref.getProxy();
		
		if (prx != null && prx.getParent() == Cat.unit) {
			tc = tc.substring(0, tc.length() - 1) + "S!" + node.getQualName() + "#" + prx.getName() + '.' + node.getName();
			return tc;
		}
		
		tc = tc.substring(0, tc.length() - 1) + "S!" + node.getQualName();

		// TODO why??
		
		for (Unit u = Cat.unit; u != null; u = u.getSuper()) {
			Decl d = Cat.ses.findDecl(u, node.getName());
			if (d != null && d.overrides() == node) {
				return tc.substring(0, tc.length() - 1) + "S!" + d.getQualName();
			}
		}
		
		return tc;
	}
	
	// recodeStr
	static String recodeStr( Decl.Struct str, String tc )
	{
		tc = tc.substring(0, tc.length() - 1) + "S!" + str.getQualName();

		// TODO why??
		
		for (Unit u = Cat.unit; u != null; u = u.getSuper()) {
			Decl d = Cat.ses.findDecl(u, str.getName());
			if (d != null && d.overrides() == str) {
				return tc.substring(0, tc.length() - 1) + "S!" + d.getQualName();
			}
		}
		
		return tc;
	}
}
