package de.dhbwstuttgart.typeinference.unify;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.HashMap;
import java.util.stream.Collectors;

import de.dhbwstuttgart.typeinference.unify.interfaces.UnifyTypeVisitor;
import de.dhbwstuttgart.typeinference.unify.model.ExtendsType;
import de.dhbwstuttgart.typeinference.unify.model.FunNType;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.ReferenceType;
import de.dhbwstuttgart.typeinference.unify.model.SuperType;
import de.dhbwstuttgart.typeinference.unify.model.TypeParams;

public class visitUnifyTypeVisitor<T> implements UnifyTypeVisitor<T> {

	public ReferenceType visit(ReferenceType refty, T ht) {
		return new ReferenceType(refty.getName(),
				new TypeParams(
						Arrays.stream(refty.getTypeParams().get())
						.map(x -> x.accept(this, ht))
						.collect(Collectors.toCollection(ArrayList::new))));
	}
	
	public PlaceholderType visit(PlaceholderType phty, T ht) {
		return phty;
	}
	
	public FunNType visit(FunNType funnty, T ht) {
		return FunNType.getFunNType(
				new TypeParams(
						Arrays.stream(funnty.getTypeParams().get())
						.map(x -> x.accept(this, ht))
						.collect(Collectors.toCollection(ArrayList::new)))
				);	
	}
	
	public SuperType visit(SuperType suty, T ht) {
		return new SuperType(suty.getWildcardedType().accept(this, ht));
	}
	
	public ExtendsType visit(ExtendsType extty, T ht) {
		return new ExtendsType(extty.getWildcardedType().accept(this, ht));
	}
}
