package de.dhbwstuttgart.strucTypes5.constraints;


import de.dhbwstuttgart.strucTypes5.algo.Type;
import de.dhbwstuttgart.strucTypes5.typeVars.TypeVar;
import de.dhbwstuttgart.strucTypes5.typeVars.TypeVarStore;
import de.dhbwstuttgart.syntaxtree.statement.Expression;
import de.dhbwstuttgart.syntaxtree.statement.FieldVar;
import de.dhbwstuttgart.syntaxtree.statement.MethodCall;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by sebastian on 20.04.17.
 */
public class ConstraintFactory {


    public static ConstraintField generateConstriantField(FieldVar fieldVar, TypeVarStore typeVarStore) {
        TypeVar revceiver = (TypeVar) typeVarStore.storeTPH(fieldVar.getReceiver().getType());
        TypeVar caller = (TypeVar) typeVarStore.storeTPH(fieldVar.getType());
        return new ConstraintField(revceiver , fieldVar.getFieldVarName() , caller);
    }



    // Methode muss constraint für methode sowie Subtype Constrainsts erstellen
    public static List<ConstraintAbstract> generateConstraintMethod(MethodCall methodCall , TypeVarStore typeVarStore) {
        TypeVar receiver =  (TypeVar) typeVarStore.storeTPH(methodCall.get_Receiver().getType());
        TypeVar caller = (TypeVar) typeVarStore.storeTPH(methodCall.getType());

        List<ConstraintAbstract> resultConstraints = new ArrayList<>();
        List<TypeVar> typeVarsArg = new ArrayList<>();
        List<TypeVar> neueTypeVars = new ArrayList<>();
        for (Expression arg : methodCall.get_ArgList().getArguments()) {

            TypeVar newVar = typeVarStore.makeFreshTypeVar();
            TypeVar oldVar = (TypeVar) typeVarStore.storeTPH(arg.getType());

            neueTypeVars.add(newVar);
            typeVarsArg.add(oldVar);

            //ConstraintSubTypeGeneric<TypeVar,TypeVar> subTypeGeneric = new ConstraintSubTypeGeneric<>(newVar,oldVar);
            ConstraintSubType subTypeGeneric = new ConstraintSubType(oldVar, newVar);
            resultConstraints.add(subTypeGeneric);
        }
        resultConstraints.add(new ConstraintMethod(receiver, methodCall.get_Name(), typeVarsArg, caller  , neueTypeVars  ));
        return resultConstraints;
    }
}
