package de.dhbwstuttgart.strucTypes5.assumptions;


import de.dhbwstuttgart.strucTypes5.constraints.ConstraintAbstract;
import de.dhbwstuttgart.strucTypes5.constraints.ConstraintSubType;
import de.dhbwstuttgart.strucTypes5.typeVars.MappingAltNeu;
import de.dhbwstuttgart.strucTypes5.typeVars.ResultTuple;
import de.dhbwstuttgart.strucTypes5.typeVars.TypeVar;
import de.dhbwstuttgart.strucTypes5.typeVars.TypeVarAbstract;

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

/**
 * This class is for using the new Operator.
 * This Class Change the TypVar and give Back a new Class for Saving in the Assumptions
 * There have to be replace the typvars in the class, the generics, and the typeVars in the constraints.
 */
public class ChangeTypeVars {


    public AssumptionClass change(AssumptionClass oldAssClass) {

        AssumptionClass assumptionClass = new AssumptionClass();

        assumptionClass.setCl(oldAssClass.getCl());


        ResultTuple resultTuple = oldAssClass.getTypeVarStore().freshVariableAndMapping();
        MappingAltNeu mappingAltNeu = resultTuple.getMappingAltNeu();


        // now make new Constraints and generics
        List<ConstraintAbstract> constraints = oldAssClass.getConstraints();
        List<ConstraintAbstract> newConstraints = new ArrayList<>();
        for (ConstraintAbstract c : constraints) {

            if (c instanceof ConstraintSubType) {
                ConstraintSubType csub = (ConstraintSubType) c;

                TypeVarAbstract tsub = csub.getSubtype();
                TypeVarAbstract tsuper = csub.getSuperType();

                TypeVarAbstract newTSub =   mappingAltNeu.getNeu(tsub);
                TypeVarAbstract newTsuper =  mappingAltNeu.getNeu(tsuper);

                ConstraintSubType newC = new ConstraintSubType(newTSub , newTsuper);
                newConstraints.add(newC);
            }
            else {
                System.err.println("Fehler bei:" + this.getClass().getName());
            }
        }


        assumptionClass.setTypeVarStore(resultTuple.getTypeVarStore());
        assumptionClass.setConstraints(newConstraints);
        assumptionClass.setGeneratedinterfaces(oldAssClass.getGeneratedinterfaces());


        // Tausche Generics aus
        List<TypeVarAbstract> genericsneu = new ArrayList<>();
        for (TypeVarAbstract tv : oldAssClass.getGenericsForClass()) {
            if (tv instanceof TypeVar) {
                TypeVar genericNeu  = (TypeVar) mappingAltNeu.getNeu(tv);
                genericsneu.add(genericNeu);
            }
        }

        assumptionClass.setGenericsForClass(genericsneu);


        // Was fehlt ist die AssumptionList
        return assumptionClass;
    }





}
