package de.dhbwstuttgart.syntaxtree.statement;

import de.dhbwstuttgart.exceptions.TypeinferenceException;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.ConstraintsFactory;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import org.antlr.v4.runtime.Token;

import java.util.HashSet;
import java.util.Set;

public class FieldVar extends Expression {

    private String fieldVarName;
    public Expression receiver;

    public FieldVar(Expression receiver, String fieldVarName, RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
        super(type, offset);
        this.fieldVarName = fieldVarName;
        this.receiver = receiver;
    }

    @Override
    public ConstraintSet getConstraints(TypeInferenceBlockInformation info) {
        ConstraintSet ret = new ConstraintSet();
        Set<Constraint> oderConstraints = new HashSet<>();
        ret.addAll(receiver.getConstraints(info));
        for(FieldAssumption fieldAssumption : info.getFields(fieldVarName)){
            Constraint constraint = new Constraint();
            constraint.add(ConstraintsFactory.createPair(
                    receiver.getType(),fieldAssumption.getReceiverType(), info));
            constraint.add(ConstraintsFactory.createPair(
                    this.getType(),fieldAssumption.getType(), info));
            oderConstraints.add(constraint);
        }
        if(oderConstraints.size() == 0)
            throw new TypeinferenceException("Kein Feld "+fieldVarName+ " gefunden", getOffset());
        ret.addOderConstraint(oderConstraints);
        return ret;
    }
    
    // @ Sebastian 
	public String getFieldVarName() {
		return fieldVarName;
	}

	// @ Sebastian
	public Expression getReceiver() {
		return receiver;
	}
    
    
    
    
    
}
