import java.util.ArrayList;

/**
 * Derived class that represents an if statement in the SILLY language.
 *   @author Dave Reed
 *   @version 1/24/22
 */
public class If extends Statement {
    private Expression test;
    private ArrayList<Statement> ifStmts;
    private ArrayList<Statement> elseStmts;

    /**
     * Reads in an if statement from the specified stream
     *   @param input the stream to be read from
     */
    public If(TokenStream input) throws Exception {
        if (!input.next().toString().equals("if")) {
            throw new Exception("SYNTAX ERROR: Malformed if statement");
        }
        this.test = new Expression(input);
        
        this.ifStmts = new ArrayList<Statement>();
        while (!input.lookAhead().toString().equals("else") && !input.lookAhead().toString().equals("end")) {
            this.ifStmts.add(Statement.getStatement(input));
        }
        
        if (input.lookAhead().toString().equals("else")) {
            input.next();
            this.elseStmts = new ArrayList<Statement>();
            while (!input.lookAhead().toString().equals("end")) {
                this.elseStmts.add(Statement.getStatement(input));
            }        	
        }
        input.next();
    }

    /**
     * Executes the current if statement.
     */
    public void execute() throws Exception {
        DataValue test = this.test.evaluate();
        if (test.getType() != DataValue.Type.BOOLEAN_VALUE) {
            throw new Exception("RUNTIME ERROR: If statement requires Boolean test.");
        } 
        else if (((Boolean) test.getValue()).booleanValue()) {
            for (Statement nextStmt : this.ifStmts) {
            	nextStmt.execute();
            }
        } 
        else if (this.elseStmts != null) {
            for (Statement nextStmt : this.elseStmts) {
            	nextStmt.execute();
            }
        }
    }

    /**
     * Converts the current if statement into a String.
     *   @return the String representation of this statement
     */
    public String toString() {
        String str = "if " + this.test;
        for (Statement stmt : this.ifStmts) {
        	str += "\n    " + stmt;
        }
        if (this.elseStmts != null) {
        	str += "\nelse";
            for (Statement stmt : this.elseStmts) {
            	str += "\n    " + stmt;
            }        	
        }
        return str + "\nend";
    }
}
