package com.example.Models.Statements;

import com.example.Exceptions.BaseException;
import com.example.Models.Expressions.IExpression;
import com.example.Models.Expressions.RelationalExpression;
import com.example.Models.Program.IDictionary;
import com.example.Models.Program.ProgramState;
import com.example.Models.Types.BooleanType;
import com.example.Models.Types.IType;

public class SwitchStatement implements IStatement{
    private IExpression exp;
    private IExpression exp1;
    private IExpression exp2;
    private IStatement stmt1;
    private IStatement stmt2;
    private IStatement stmt3;

    public SwitchStatement(IExpression exp,IExpression exp1, IExpression exp2, IStatement stmt1, IStatement stmt2, IStatement stmt3){
        this.exp = exp;
        this.exp1 = exp1;
        this.exp2 = exp2;
        this.stmt1 = stmt1;
        this.stmt2 = stmt2;
        this.stmt3 = stmt3;
    }

    public ProgramState execute(ProgramState state) throws BaseException{
        var stack = state.getStack();
        var ifstmt = new IfStatement(new RelationalExpression(exp, exp1, "=="), stmt1 , new IfStatement(new RelationalExpression(exp, exp2, "=="), stmt2, stmt3));
        stack.push(ifstmt);
        return null;
    }
    public IStatement copy(){
        return new SwitchStatement(exp, exp1, exp2, stmt1, stmt2, stmt3);
    }
    public IDictionary<String, IType> typeCheck(IDictionary<String, IType> typeTable) throws BaseException{
        IType expType = exp.typeCheck(typeTable);
        IType exp1Type = exp1.typeCheck(typeTable);
        IType exp2Type = exp2.typeCheck(typeTable);
        if (expType.equals(exp1Type) && expType.equals(exp2Type)) {
            stmt1.typeCheck(typeTable.copy());
            stmt2.typeCheck(typeTable.copy());
            stmt3.typeCheck(typeTable.copy());
            return typeTable;
        } else {
            throw new BaseException("Condition is not a boolean!");
        }
    }

    public String toString(){
        return "(switch(" + exp +") (case(" + exp1 + ") : " + stmt1 + ") (case (" + exp2 + ") : " + stmt2 + ") (default : " + stmt3 + "))"; 
    }
}
