package de.dhbwstuttgart.strucTypes4.syntaxtree;

import de.dhbwstuttgart.strucTypes4.algo.ConstraintAbstract;
import de.dhbwstuttgart.strucTypes4.algo.TypeExpr;
import de.dhbwstuttgart.strucTypes4.typePlaceHolder.TPH;
import de.dhbwstuttgart.strucTypes4.typeVars.TypeVarAbstract;
import de.dhbwstuttgart.strucTypes4.typeVars.TypeVarStore;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by sebastian on 07.04.17.
 */
public class Method extends  SyntaxNode {

    private String name;
    private String rtype;
    private List<Argument> args;
    private ExpressionAbstract expression;


    public Method(String name, String rtype, List<Argument> args, ExpressionAbstract expression) {
        this.name = name;
        this.rtype = rtype;
        this.args = args;
        this.expression = expression;
    }


    public Map<String, TypeVarAbstract> makeAssumptions(TypeVarStore typeVarStore)  {
        Map<String, TypeVarAbstract> assLokal = new HashMap<>();
        for (Argument arg :  args ) {
            TypeVarAbstract tv = typeVarStore.storeTPH(arg.getTypePlaceHolder());
            assLokal.put(arg.getName(), tv  );
        }
        return assLokal;
    }

    public List<ConstraintAbstract> typeExpr(Map<String,TypeVarAbstract> ass, TypeVarStore typeVarStore) {
        return TypeExpr.typeExpr(expression,ass,null , null , typeVarStore);
    }





    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getRtype() {
        return rtype;
    }

    public void setRtype(String rtype) {
        this.rtype = rtype;
    }

    public List<Argument> getArgs() {
        return args;
    }

    public void setArgs(List<Argument> args) {
        this.args = args;
    }

    public ExpressionAbstract getExpression() {
        return expression;
    }

    public void setExpression(ExpressionAbstract expression) {
        this.expression = expression;
    }


    public String toString() {
     return String.format("Methode:  %s ( %s ) { return  %s }" , name , args.toString() , expression.toString());
    }


    @Override
    public String toCodeTPH() {

        String argsString = "";
        for (Argument argument : args) {
            argsString = argsString.concat(argument.toCodeTPH() + " ");
        }
        return String.format("%s Methode:  %s ( %s ) { return  %s }" , expression.getTypePlaceHolder(), name , argsString , expression.toCodeTPH() );
    }


    @Override
    public String toCodeTyped(TypeVarStore typeVarStore) {

        String argsString = "";
        for (Argument argument : args) {
            argsString = argsString.concat(argument.toCodeTyped(typeVarStore) + " ");
        }

        //TPH rec = ((Expression) expression).getTypePlaceHolder();
        TPH rec = expression.getTypePlaceHolder();
        //System.out.println(rec);
        return String.format("%s Methode:  %s ( %s ) { return  %s }" , typeVarStore.getTypeVarByTPH(rec), name , argsString , expression.toCodeTyped(typeVarStore) );
    }

}
