package de.dhbwstuttgart.bytecode.signature;

import java.util.Iterator;

import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.syntaxtree.type.TypeVisitor;

public class TypeToSignature implements TypeVisitor<String> {

	@Override
	public String visit(RefType refType) {
		if(refType.getName().toString().equals("void"))
			return "V";
//		return refType.toString().replace(".", "/");
		String params = "";
        if(refType.getParaList().size()>0){
            params += "<";
            Iterator<RefTypeOrTPHOrWildcardOrGeneric> it = refType.getParaList().iterator();
            while(it.hasNext()){
                RefTypeOrTPHOrWildcardOrGeneric param = it.next();
//                if(param instanceof TypePlaceholder) {
//                	params += "T" + ((TypePlaceholder) param).getName() + "$";
//                } else if(param instanceof ExtendsWildcardType) {
//                	params += "+" + ((ExtendsWildcardType) param).getInnerType().acceptTV(new TypeToSignature());
//                } else if(param instanceof SuperWildcardType) {
//                	params += "-" + ((SuperWildcardType) param).getInnerType().acceptTV(new TypeToSignature());
//                } else {
//                		params += "L"+param.toString().replace(".", "/");
//                }
                params += param.acceptTV(new TypeToSignature());

                if(param instanceof TypePlaceholder)
                	params += ";";
            }
            params += ">";
        }
//        		String t = refType.getName().toString().replace(".", "/");
//        		return t.equals("Fun1")?t+"$$"+params+";":t+params+";";
        return "L"+refType.getName().toString().replace(".", "/") + params+";";
	}

	@Override
	public String visit(SuperWildcardType superWildcardType) {
//		throw new NotImplementedException();
		String sig = "-" + superWildcardType.getInnerType().acceptTV(new TypeToSignature());
		if(superWildcardType.getInnerType() instanceof TypePlaceholder)
			sig += ";";
		return sig;
	}

	@Override
	public String visit(TypePlaceholder typePlaceholder) {
//		return typePlaceholder.toString().replace(".", "/");
		return "T" + typePlaceholder.getName() + "$";
	}

	@Override
	public String visit(ExtendsWildcardType extendsWildcardType) {
//		throw new NotImplementedException();
		String sig = "+" + extendsWildcardType.getInnerType().acceptTV(new TypeToSignature());
		if(extendsWildcardType.getInnerType() instanceof TypePlaceholder)
			sig += ";";
		return sig;
	}

	@Override
	public String visit(GenericRefType genericRefType) {
		return genericRefType.getParsedName().replace(".", "/");
	}
	
}
