package generators;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import ast.CompilationUnit;
import ast.SimpleType;
import models.algebra.Type;
import models.dataConstraintModel.MapType;

public class Codebase {
	private Map<String, CompilationUnit> classes = new HashMap<>();
	private Map<String, models.algebra.Type> componentTypes = new HashMap<>();
	private Map<String, models.algebra.Type> standardTypes = new HashMap<>();
	
	public Codebase() {
	}
	
	public Collection<CompilationUnit> getCompilationUnits() {
		return classes.values();
	}
	
	public CompilationUnit getCompilationUnit(String name) {
		return classes.get(name);
	}
	
	public models.algebra.Type getComponentType(String typeName) {
		return componentTypes.get(typeName);
	}
	
	public models.algebra.Type getOrCreateStandardType(String typeName) {
		models.algebra.Type type = standardTypes.get(typeName);
		if (type == null) {
			type = new models.algebra.Type(typeName, new SimpleType(typeName));
			standardTypes.put(typeName, type);
		}
		return type;
	}

	public MapType getMapType(String keyTypeName, String valueTypeName) {
		models.algebra.Type valueType = componentTypes.get(valueTypeName);
		if (valueType == null) {
			valueType = getOrCreateStandardType(valueTypeName);
		}
		models.algebra.Type keyType = getOrCreateStandardType(keyTypeName);
		return new MapType("map", new SimpleType("HashMap<>"), new SimpleType("Map<" + keyTypeName + ", " + valueTypeName + ">"), keyType, valueType);
	}

	public void addCompilationUnit(String name, CompilationUnit compilationUnit) {
		classes.put(name, compilationUnit);
		models.algebra.Type newType = new models.algebra.Type(name, new SimpleType(name));
		componentTypes.put(name, newType);
	}
	
	public String toString() {
		String code = "";
		for (CompilationUnit cu: classes.values()) {
			code += cu.toString();
		}
		return code;
	}
}
