// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use crate::bind_program::{Condition, ConditionOp, Statement};
use crate::compiler::{self, Symbol, SymbolTable, SymbolicInstruction, SymbolicInstructionInfo};
use crate::device_specification::{DeviceSpecification, Property};
use crate::errors::UserError;
use crate::instruction::{InstructionDebug, RawAstLocation};
use crate::parser_common::{self, CompoundIdentifier, Span, Value};
use std::collections::{HashMap, HashSet};
use std::fmt;
use std::str::FromStr;
use thiserror::Error;

#[derive(Debug, Error, Clone, PartialEq)]
pub enum DebuggerError {
    BindParserError(parser_common::BindParserError),
    CompilerError(compiler::CompilerError),
    DuplicateKey(CompoundIdentifier),
    MissingLabel,
    NoOutcome,
    IncorrectAstLocation,
    InvalidAstLocation,
    UnknownKey(CompoundIdentifier),
    InvalidValueSymbol(Symbol),
}

impl fmt::Display for DebuggerError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", UserError::from(self.clone()))
    }
}

type DevicePropertyMap = HashMap<Symbol, DeviceValue>;

#[derive(Debug, PartialEq)]
struct DeviceValue {
    symbol: Option<Symbol>,
    identifier: Option<CompoundIdentifier>,
}

#[derive(Debug, PartialEq)]
pub enum AstLocation<'a> {
    ConditionStatement(Statement<'a>),
    AcceptStatementValue { identifier: CompoundIdentifier, value: Value, span: Span<'a> },
    AcceptStatementFailure { identifier: CompoundIdentifier, symbol: Symbol, span: Span<'a> },
    IfCondition(Condition<'a>),
    AbortStatement(Statement<'a>),
}

impl<'a> AstLocation<'a> {
    pub fn to_instruction_debug(self) -> InstructionDebug {
        match self {
            AstLocation::ConditionStatement(statement) => InstructionDebug {
                line: statement.get_span().line,
                ast_location: RawAstLocation::ConditionStatement,
                extra: 0,
            },
            AstLocation::AcceptStatementValue { span, .. } => InstructionDebug {
                line: span.line,
                ast_location: RawAstLocation::AcceptStatementValue,
                extra: 0,
            },
            AstLocation::AcceptStatementFailure { span, symbol, .. } => InstructionDebug {
                line: span.line,
                ast_location: RawAstLocation::AcceptStatementFailure,
                extra: symbol.to_bytecode(),
            },
            AstLocation::IfCondition(condition) => InstructionDebug {
                line: condition.span.line,
                ast_location: RawAstLocation::IfCondition,
                extra: 0,
            },
            AstLocation::AbortStatement(statement) => InstructionDebug {
                line: statement.get_span().line,
                ast_location: RawAstLocation::AbortStatement,
                extra: 0,
            },
        }
    }
}

#[derive(Debug, PartialEq)]
enum DebuggerOutput<'a> {
    ConditionStatement {
        statement: &'a Statement<'a>,
        success: bool,
    },
    AbortStatement {
        statement: &'a Statement<'a>,
    },
    AcceptStatementSuccess {
        identifier: &'a CompoundIdentifier,
        value: &'a Value,
        value_symbol: &'a Symbol,
        span: &'a Span<'a>,
    },
    AcceptStatementFailure {
        identifier: &'a CompoundIdentifier,
        span: &'a Span<'a>,
    },
    IfCondition {
        condition: &'a Condition<'a>,
        success: bool,
    },
}

pub fn debug_from_str<'a>(
    instructions: &[SymbolicInstructionInfo<'a>],
    symbol_table: &SymbolTable,
    device_file: &str,
) -> Result<bool, DebuggerError> {
    let device_specification =
        DeviceSpecification::from_str(device_file).map_err(DebuggerError::BindParserError)?;

    debug_from_device_specification(instructions, symbol_table, device_specification)
}

pub fn debug_from_device_specification<'a>(
    instructions: &[SymbolicInstructionInfo<'a>],
    symbol_table: &SymbolTable,
    device_specification: DeviceSpecification,
) -> Result<bool, DebuggerError> {
    let mut debugger = Debugger::new(&device_specification.properties, instructions, symbol_table)?;
    let binds = debugger.evaluate_bind_program()?;
    debugger.log_output()?;
    Ok(binds)
}

struct Debugger<'a> {
    device_properties: DevicePropertyMap,
    instructions: &'a [SymbolicInstructionInfo<'a>],
    symbol_table: &'a SymbolTable,
    output: Vec<DebuggerOutput<'a>>,
}

impl<'a> Debugger<'a> {
    fn new(
        properties: &[Property],
        instructions: &'a [SymbolicInstructionInfo<'a>],
        symbol_table: &'a SymbolTable,
    ) -> Result<Self, DebuggerError> {
        let device_properties = Debugger::construct_property_map(properties, symbol_table)?;
        let output = Vec::new();
        Ok(Debugger { device_properties, instructions, symbol_table, output })
    }

    /// Constructs a map of the device's properties. The keys are of type Symbol, and only keys
    /// which appear in the bind program's symbol table are included. Any other keys in the device
    /// specification can be safely ignored, since the bind program won't check their values. The
    /// values are a struct containing both a symbol and an identifier, to allow the debugger to
    /// output both the identifier and the literal value it corresponds to when printing values.
    /// Both these fields are optional. If the symbol is None, then the device value is an
    /// identifier not defined in the symbol table. If the identifier is None, then the device
    /// value is a literal.
    fn construct_property_map(
        properties: &[Property],
        symbol_table: &SymbolTable,
    ) -> Result<DevicePropertyMap, DebuggerError> {
        let mut property_map = HashMap::new();
        let mut keys_seen = HashSet::new();

        for Property { key, value } in properties {
            // Check for duplicate keys in the device specification. This is done using a separate
            // set since the property_map only contains keys which are present in the symbol table.
            if keys_seen.contains(key) {
                return Err(DebuggerError::DuplicateKey(key.clone()));
            }
            keys_seen.insert(key.clone());

            if let Some(key_symbol) = symbol_table.get(key) {
                let device_value = match value {
                    Value::NumericLiteral(n) => {
                        DeviceValue { symbol: Some(Symbol::NumberValue(*n)), identifier: None }
                    }
                    Value::StringLiteral(s) => DeviceValue {
                        symbol: Some(Symbol::StringValue(s.to_string())),
                        identifier: None,
                    },
                    Value::BoolLiteral(b) => {
                        DeviceValue { symbol: Some(Symbol::BoolValue(*b)), identifier: None }
                    }
                    Value::Identifier(identifier) => match symbol_table.get(identifier) {
                        Some(symbol) => DeviceValue {
                            symbol: Some(symbol.clone()),
                            identifier: Some(identifier.clone()),
                        },
                        None => DeviceValue { symbol: None, identifier: Some(identifier.clone()) },
                    },
                };

                property_map.insert(key_symbol.clone(), device_value);
            }
        }

        Ok(property_map)
    }

    fn evaluate_bind_program(&mut self) -> Result<bool, DebuggerError> {
        let mut instructions = self.instructions.iter();

        while let Some(mut instruction) = instructions.next() {
            let mut jump_label = None;

            match &instruction.instruction {
                SymbolicInstruction::AbortIfEqual { lhs, rhs } => {
                    let aborts = self.device_property_matches(lhs, rhs);
                    self.output_abort_if(&instruction.location, aborts)?;
                    if aborts {
                        return Ok(false);
                    }
                }
                SymbolicInstruction::AbortIfNotEqual { lhs, rhs } => {
                    let aborts = !self.device_property_matches(lhs, rhs);
                    self.output_abort_if(&instruction.location, aborts)?;
                    if aborts {
                        return Ok(false);
                    }
                }
                SymbolicInstruction::Label(_label) => (),
                SymbolicInstruction::UnconditionalJump { label } => {
                    jump_label = Some(label);
                }
                SymbolicInstruction::JumpIfEqual { lhs, rhs, label } => {
                    let jump_succeeds = self.device_property_matches(lhs, rhs);
                    self.output_jump_if_equal(&instruction.location, rhs, jump_succeeds)?;
                    if jump_succeeds {
                        jump_label = Some(label);
                    }
                }
                SymbolicInstruction::JumpIfNotEqual { lhs, rhs, label } => {
                    let jump_succeeds = !self.device_property_matches(lhs, rhs);
                    self.output_jump_if_not_equal(&instruction.location, jump_succeeds)?;
                    if jump_succeeds {
                        jump_label = Some(label);
                    }
                }
                SymbolicInstruction::UnconditionalAbort => {
                    self.output_unconditional_abort(&instruction.location)?;
                    return Ok(false);
                }
                SymbolicInstruction::UnconditionalBind => return Ok(true),
            }

            if let Some(label) = jump_label {
                while instruction.instruction != SymbolicInstruction::Label(*label) {
                    instruction = instructions.next().ok_or(DebuggerError::MissingLabel)?;
                }
            }
        }

        Err(DebuggerError::NoOutcome)
    }

    fn device_property_matches(&self, lhs: &Symbol, rhs: &Symbol) -> bool {
        if let Some(DeviceValue { symbol: Some(value_symbol), identifier: _ }) =
            self.device_properties.get(lhs)
        {
            value_symbol == rhs
        } else {
            false
        }
    }

    fn output_abort_if(
        &mut self,
        location: &'a Option<AstLocation>,
        aborts: bool,
    ) -> Result<(), DebuggerError> {
        if let Some(AstLocation::ConditionStatement(statement)) = location {
            self.output.push(DebuggerOutput::ConditionStatement { statement, success: !aborts });
            Ok(())
        } else {
            Err(DebuggerError::IncorrectAstLocation)
        }
    }

    fn output_jump_if_equal(
        &mut self,
        location: &'a Option<AstLocation>,
        rhs: &'a Symbol,
        jump_succeeds: bool,
    ) -> Result<(), DebuggerError> {
        match location {
            Some(AstLocation::AcceptStatementValue { identifier, value, span }) => {
                if jump_succeeds {
                    self.output.push(DebuggerOutput::AcceptStatementSuccess {
                        identifier,
                        value,
                        value_symbol: rhs,
                        span,
                    });
                }
                Ok(())
            }
            Some(AstLocation::IfCondition(condition)) => {
                self.output
                    .push(DebuggerOutput::IfCondition { condition, success: !jump_succeeds });
                Ok(())
            }
            _ => Err(DebuggerError::IncorrectAstLocation),
        }
    }

    fn output_jump_if_not_equal(
        &mut self,
        location: &'a Option<AstLocation>,
        jump_succeeds: bool,
    ) -> Result<(), DebuggerError> {
        if let Some(AstLocation::IfCondition(condition)) = location {
            self.output.push(DebuggerOutput::IfCondition { condition, success: !jump_succeeds });
            Ok(())
        } else {
            Err(DebuggerError::IncorrectAstLocation)
        }
    }

    fn output_unconditional_abort(
        &mut self,
        location: &'a Option<AstLocation>,
    ) -> Result<(), DebuggerError> {
        match location {
            Some(AstLocation::AbortStatement(statement)) => {
                self.output.push(DebuggerOutput::AbortStatement { statement });
                Ok(())
            }
            Some(AstLocation::AcceptStatementFailure { identifier, span, symbol: _ }) => {
                self.output.push(DebuggerOutput::AcceptStatementFailure { identifier, span });
                Ok(())
            }
            _ => Err(DebuggerError::IncorrectAstLocation),
        }
    }

    fn log_output(&self) -> Result<(), DebuggerError> {
        for output in &self.output {
            match output {
                DebuggerOutput::ConditionStatement { statement, success } => {
                    self.log_condition_statement(statement, *success)?;
                }
                DebuggerOutput::AbortStatement { statement } => self.log_abort_statement(statement),
                DebuggerOutput::AcceptStatementSuccess {
                    identifier,
                    value,
                    value_symbol,
                    span,
                } => self.log_accept_statement_success(identifier, value, value_symbol, span)?,
                DebuggerOutput::AcceptStatementFailure { identifier, span } => {
                    self.log_accept_statement_failure(identifier, span)?;
                }
                DebuggerOutput::IfCondition { condition, success } => {
                    self.log_if_condition(condition, *success)?;
                }
            }
        }
        Ok(())
    }

    fn log_condition_statement(
        &self,
        statement: &Statement,
        success: bool,
    ) -> Result<(), DebuggerError> {
        if let Statement::ConditionStatement { span, condition: Condition { lhs, op, .. } } =
            statement
        {
            let outcome_string = if success { "succeeded" } else { "failed" };
            println!(
                "Line {}: Condition statement {}: {}",
                span.line, outcome_string, span.fragment
            );

            if condition_needs_actual_value(success, op) {
                println!("\t{}", self.actual_value_string(lhs)?)
            }

            Ok(())
        } else {
            Err(DebuggerError::InvalidAstLocation)
        }
    }

    fn log_abort_statement(&self, statement: &Statement) {
        if let Statement::Abort { span } = statement {
            println!("Line {}: Abort statement reached.", span.line);
        }
    }

    fn log_accept_statement_success(
        &self,
        identifier: &CompoundIdentifier,
        value: &Value,
        value_symbol: &Symbol,
        span: &Span,
    ) -> Result<(), DebuggerError> {
        // Get the value identifier from the accept statement (or None for a literal value).
        let value_identifier_prog =
            if let Value::Identifier(identifier) = value { Some(identifier) } else { None };

        // Get the value identifier from the device specification (or None for a literal value).
        let key_symbol = self
            .symbol_table
            .get(identifier)
            .ok_or(DebuggerError::UnknownKey(identifier.clone()))?;
        let DeviceValue { symbol: _, identifier: value_identifier_device } = self
            .device_properties
            .get(key_symbol)
            .expect("Accept statement succeeded so device must have this key.");

        let value_literal = value_symbol_string(value_symbol)?;

        let value_string = match (value_identifier_prog, value_identifier_device) {
            (Some(identifier_prog), Some(identifier_value)) => {
                if identifier_prog == identifier_value {
                    format!("`{}` [{}]", identifier_prog, value_literal)
                } else {
                    format!("`{}` (`{}`) [{}]", identifier_prog, identifier_value, value_literal)
                }
            }
            (Some(identifier_prog), None) => format!("`{}` [{}]", identifier_prog, value_literal),
            (None, Some(identifier_value)) => format!("`{}` [{}]", identifier_value, value_literal),
            (None, None) => format!("{}", value_literal),
        };

        println!(
            "Line {}: Accept statement succeeded.\n\tValue of `{}` was {}.",
            span.line, identifier, value_string
        );

        Ok(())
    }

    fn log_accept_statement_failure(
        &self,
        identifier: &CompoundIdentifier,
        span: &Span,
    ) -> Result<(), DebuggerError> {
        println!(
            "Line {}: Accept statement failed.\n\t{}",
            span.line,
            self.actual_value_string(identifier)?
        );

        Ok(())
    }

    fn log_if_condition(&self, condition: &Condition, success: bool) -> Result<(), DebuggerError> {
        let Condition { span, lhs, op, rhs: _ } = condition;

        let outcome_string = if success { "succeeded" } else { "failed" };
        println!(
            "Line {}: If statement condition {}: {}",
            span.line, outcome_string, span.fragment
        );

        if condition_needs_actual_value(success, op) {
            println!("\t{}", self.actual_value_string(lhs)?)
        }

        Ok(())
    }

    fn actual_value_string(
        &self,
        key_identifier: &CompoundIdentifier,
    ) -> Result<String, DebuggerError> {
        let key_symbol = self
            .symbol_table
            .get(key_identifier)
            .ok_or(DebuggerError::UnknownKey(key_identifier.clone()))?;
        let DeviceValue { symbol: value_symbol, identifier: value_identifier } = self
            .device_properties
            .get(key_symbol)
            .unwrap_or(&DeviceValue { symbol: None, identifier: None });

        Ok(match (value_symbol, value_identifier) {
            (Some(symbol), Some(identifier)) => format!(
                "Actual value of `{}` was `{}` [{}].",
                key_identifier,
                identifier,
                value_symbol_string(symbol)?
            ),
            (Some(symbol), None) => format!(
                "Actual value of `{}` was literal {}.",
                key_identifier,
                value_symbol_string(symbol)?
            ),
            (None, Some(identifier)) => {
                format!("Actual value of `{}` was `{}`.", key_identifier, identifier)
            }
            (None, None) => format!("Device had no value for `{}`.", key_identifier),
        })
    }
}

fn condition_needs_actual_value(success: bool, op: &ConditionOp) -> bool {
    match op {
        ConditionOp::Equals => !success,
        ConditionOp::NotEquals => success,
    }
}

fn value_symbol_string(symbol: &Symbol) -> Result<String, DebuggerError> {
    match symbol {
        Symbol::DeprecatedKey(..) => Err(DebuggerError::InvalidValueSymbol(symbol.clone())),
        Symbol::Key(..) => Err(DebuggerError::InvalidValueSymbol(symbol.clone())),
        Symbol::NumberValue(n) => Ok(format!("0x{:x}", n)),
        Symbol::StringValue(s) => Ok(format!("\"{}\"", s)),
        Symbol::BoolValue(b) => Ok(b.to_string()),
        Symbol::EnumValue => unimplemented!("Enum values are unsupported."),
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use crate::bind_library;
    use crate::bind_program::{Condition, ConditionOp, Statement};
    use crate::make_identifier;
    use crate::parser_common::{CompoundIdentifier, Span};

    #[test]
    fn duplicate_key() {
        let symbol_table = HashMap::new();
        let properties = vec![
            Property { key: make_identifier!("abc"), value: Value::NumericLiteral(42) },
            Property { key: make_identifier!("abc"), value: Value::NumericLiteral(5) },
        ];
        assert_eq!(
            Debugger::construct_property_map(&properties, &symbol_table),
            Err(DebuggerError::DuplicateKey(make_identifier!("abc")))
        );
    }

    #[test]
    fn condition_equals() {
        let statement = Statement::ConditionStatement {
            span: Span::new(),
            condition: Condition {
                span: Span::new(),
                lhs: make_identifier!("abc"),
                op: ConditionOp::Equals,
                rhs: Value::NumericLiteral(42),
            },
        };
        let statements = vec![statement.clone()];
        let mut symbol_table = HashMap::new();
        symbol_table.insert(
            make_identifier!("abc"),
            Symbol::Key("abc".to_string(), bind_library::ValueType::Number),
        );
        let instructions = compiler::compile_statements(statements, &symbol_table).unwrap();

        // Binds when the device has the correct property.
        let properties =
            vec![Property { key: make_identifier!("abc"), value: Value::NumericLiteral(42) }];
        let mut debugger = Debugger::new(&properties, &instructions, &symbol_table).unwrap();
        assert!(debugger.evaluate_bind_program().unwrap());
        assert_eq!(
            debugger.output,
            vec![DebuggerOutput::ConditionStatement { statement: &statement, success: true }]
        );

        // Binds when other properties are present as well.
        let properties = vec![
            Property { key: make_identifier!("abc"), value: Value::NumericLiteral(42) },
            Property { key: make_identifier!("xyz"), value: Value::BoolLiteral(true) },
        ];
        let mut debugger = Debugger::new(&properties, &instructions, &symbol_table).unwrap();
        assert!(debugger.evaluate_bind_program().unwrap());
        assert_eq!(
            debugger.output,
            vec![DebuggerOutput::ConditionStatement { statement: &statement, success: true }]
        );

        // Doesn't bind when the device has the wrong value for the property.
        let properties =
            vec![Property { key: make_identifier!("abc"), value: Value::NumericLiteral(5) }];
        let mut debugger = Debugger::new(&properties, &instructions, &symbol_table).unwrap();
        assert!(!debugger.evaluate_bind_program().unwrap());
        assert_eq!(
            debugger.output,
            vec![DebuggerOutput::ConditionStatement { statement: &statement, success: false }]
        );

        // Doesn't bind when the property is not present in the device.
        let properties = Vec::new();
        let mut debugger = Debugger::new(&properties, &instructions, &symbol_table).unwrap();
        assert!(!debugger.evaluate_bind_program().unwrap());
        assert_eq!(
            debugger.output,
            vec![DebuggerOutput::ConditionStatement { statement: &statement, success: false }]
        );
    }

    #[test]
    fn condition_not_equals() {
        let statement = Statement::ConditionStatement {
            span: Span::new(),
            condition: Condition {
                span: Span::new(),
                lhs: make_identifier!("abc"),
                op: ConditionOp::NotEquals,
                rhs: Value::NumericLiteral(42),
            },
        };
        let statements = vec![statement.clone()];
        let mut symbol_table = HashMap::new();
        symbol_table.insert(
            make_identifier!("abc"),
            Symbol::Key("abc".to_string(), bind_library::ValueType::Number),
        );
        let instructions = compiler::compile_statements(statements, &symbol_table).unwrap();

        // Binds when the device has a different value for the property.
        let properties =
            vec![Property { key: make_identifier!("abc"), value: Value::NumericLiteral(5) }];
        let mut debugger = Debugger::new(&properties, &instructions, &symbol_table).unwrap();
        assert!(debugger.evaluate_bind_program().unwrap());
        assert_eq!(
            debugger.output,
            vec![DebuggerOutput::ConditionStatement { statement: &statement, success: true }]
        );

        // Binds when the property is not present in the device.
        let properties = Vec::new();
        let mut debugger = Debugger::new(&properties, &instructions, &symbol_table).unwrap();
        assert!(debugger.evaluate_bind_program().unwrap());
        assert_eq!(
            debugger.output,
            vec![DebuggerOutput::ConditionStatement { statement: &statement, success: true }]
        );

        // Doesn't bind when the device has the property in the condition statement.
        let properties =
            vec![Property { key: make_identifier!("abc"), value: Value::NumericLiteral(42) }];
        let mut debugger = Debugger::new(&properties, &instructions, &symbol_table).unwrap();
        assert!(!debugger.evaluate_bind_program().unwrap());
        assert_eq!(
            debugger.output,
            vec![DebuggerOutput::ConditionStatement { statement: &statement, success: false }]
        );
    }

    #[test]
    fn accept() {
        let statements = vec![Statement::Accept {
            span: Span::new(),
            identifier: make_identifier!("abc"),
            values: vec![Value::NumericLiteral(42), Value::NumericLiteral(314)],
        }];
        let mut symbol_table = HashMap::new();
        symbol_table.insert(
            make_identifier!("abc"),
            Symbol::Key("abc".to_string(), bind_library::ValueType::Number),
        );

        let instructions = compiler::compile_statements(statements, &symbol_table).unwrap();

        // Binds when the device has one of the accepted values for the property.
        let properties =
            vec![Property { key: make_identifier!("abc"), value: Value::NumericLiteral(42) }];
        let mut debugger = Debugger::new(&properties, &instructions, &symbol_table).unwrap();
        assert!(debugger.evaluate_bind_program().unwrap());
        assert_eq!(
            debugger.output,
            vec![DebuggerOutput::AcceptStatementSuccess {
                identifier: &make_identifier!("abc"),
                value: &Value::NumericLiteral(42),
                value_symbol: &Symbol::NumberValue(42),
                span: &Span::new(),
            }]
        );

        // Doesn't bind when the device has a different value for the property.
        let properties =
            vec![Property { key: make_identifier!("abc"), value: Value::NumericLiteral(5) }];
        let mut debugger = Debugger::new(&properties, &instructions, &symbol_table).unwrap();
        assert!(!debugger.evaluate_bind_program().unwrap());
        assert_eq!(
            debugger.output,
            vec![DebuggerOutput::AcceptStatementFailure {
                identifier: &make_identifier!("abc"),
                span: &Span::new(),
            }]
        );

        // Doesn't bind when the device is missing the property.
        let properties = Vec::new();
        let mut debugger = Debugger::new(&properties, &instructions, &symbol_table).unwrap();
        assert!(!debugger.evaluate_bind_program().unwrap());
        assert_eq!(
            debugger.output,
            vec![DebuggerOutput::AcceptStatementFailure {
                identifier: &make_identifier!("abc"),
                span: &Span::new(),
            }]
        );
    }

    #[test]
    fn if_else() {
        /*
        if abc == 1 {
            xyz == 1;
        } else if abc == 2{
            xyz == 2;
        } else {
            xyz == 3;
        }
        */

        let condition1 = Condition {
            span: Span::new(),
            lhs: make_identifier!("abc"),
            op: ConditionOp::Equals,
            rhs: Value::NumericLiteral(1),
        };
        let condition2 = Condition {
            span: Span::new(),
            lhs: make_identifier!("abc"),
            op: ConditionOp::Equals,
            rhs: Value::NumericLiteral(2),
        };
        let statement1 = Statement::ConditionStatement {
            span: Span::new(),
            condition: Condition {
                span: Span::new(),
                lhs: make_identifier!("xyz"),
                op: ConditionOp::Equals,
                rhs: Value::NumericLiteral(1),
            },
        };
        let statement2 = Statement::ConditionStatement {
            span: Span::new(),
            condition: Condition {
                span: Span::new(),
                lhs: make_identifier!("xyz"),
                op: ConditionOp::Equals,
                rhs: Value::NumericLiteral(2),
            },
        };
        let statement3 = Statement::ConditionStatement {
            span: Span::new(),
            condition: Condition {
                span: Span::new(),
                lhs: make_identifier!("xyz"),
                op: ConditionOp::Equals,
                rhs: Value::NumericLiteral(3),
            },
        };

        let statements = vec![Statement::If {
            span: Span::new(),
            blocks: vec![
                (condition1.clone(), vec![statement1.clone()]),
                (condition2.clone(), vec![statement2.clone()]),
            ],
            else_block: vec![statement3.clone()],
        }];
        let mut symbol_table = HashMap::new();
        symbol_table.insert(
            make_identifier!("abc"),
            Symbol::Key("abc".to_string(), bind_library::ValueType::Number),
        );
        symbol_table.insert(
            make_identifier!("xyz"),
            Symbol::Key("xyz".to_string(), bind_library::ValueType::Number),
        );

        let instructions = compiler::compile_statements(statements, &symbol_table).unwrap();

        // Binds when the if clause is satisfied.
        let properties = vec![
            Property { key: make_identifier!("abc"), value: Value::NumericLiteral(1) },
            Property { key: make_identifier!("xyz"), value: Value::NumericLiteral(1) },
        ];
        let mut debugger = Debugger::new(&properties, &instructions, &symbol_table).unwrap();
        assert!(debugger.evaluate_bind_program().unwrap());
        assert_eq!(
            debugger.output,
            vec![
                DebuggerOutput::IfCondition { condition: &condition1, success: true },
                DebuggerOutput::ConditionStatement { statement: &statement1, success: true }
            ]
        );

        // Binds when the if else clause is satisfied.
        let properties = vec![
            Property { key: make_identifier!("abc"), value: Value::NumericLiteral(2) },
            Property { key: make_identifier!("xyz"), value: Value::NumericLiteral(2) },
        ];
        let mut debugger = Debugger::new(&properties, &instructions, &symbol_table).unwrap();
        assert!(debugger.evaluate_bind_program().unwrap());
        assert_eq!(
            debugger.output,
            vec![
                DebuggerOutput::IfCondition { condition: &condition1, success: false },
                DebuggerOutput::IfCondition { condition: &condition2, success: true },
                DebuggerOutput::ConditionStatement { statement: &statement2, success: true }
            ]
        );

        // Binds when the else clause is satisfied.
        let properties =
            vec![Property { key: make_identifier!("xyz"), value: Value::NumericLiteral(3) }];
        let mut debugger = Debugger::new(&properties, &instructions, &symbol_table).unwrap();
        assert!(debugger.evaluate_bind_program().unwrap());
        assert_eq!(
            debugger.output,
            vec![
                DebuggerOutput::IfCondition { condition: &condition1, success: false },
                DebuggerOutput::IfCondition { condition: &condition2, success: false },
                DebuggerOutput::ConditionStatement { statement: &statement3, success: true }
            ]
        );

        // Doesn't bind when the device has incorrect values for the properties.
        let properties = vec![
            Property { key: make_identifier!("abc"), value: Value::NumericLiteral(42) },
            Property { key: make_identifier!("xyz"), value: Value::NumericLiteral(42) },
        ];
        let mut debugger = Debugger::new(&properties, &instructions, &symbol_table).unwrap();
        assert!(!debugger.evaluate_bind_program().unwrap());
        assert_eq!(
            debugger.output,
            vec![
                DebuggerOutput::IfCondition { condition: &condition1, success: false },
                DebuggerOutput::IfCondition { condition: &condition2, success: false },
                DebuggerOutput::ConditionStatement { statement: &statement3, success: false }
            ]
        );

        // Doesn't bind when the properties are missing in the device.
        let properties = Vec::new();
        let mut debugger = Debugger::new(&properties, &instructions, &symbol_table).unwrap();
        assert!(!debugger.evaluate_bind_program().unwrap());
        assert_eq!(
            debugger.output,
            vec![
                DebuggerOutput::IfCondition { condition: &condition1, success: false },
                DebuggerOutput::IfCondition { condition: &condition2, success: false },
                DebuggerOutput::ConditionStatement { statement: &statement3, success: false }
            ]
        );
    }

    #[test]
    fn abort() {
        let condition_statement = Statement::ConditionStatement {
            span: Span::new(),
            condition: Condition {
                span: Span::new(),
                lhs: make_identifier!("abc"),
                op: ConditionOp::Equals,
                rhs: Value::NumericLiteral(42),
            },
        };
        let abort_statement = Statement::Abort { span: Span::new() };
        let statements = vec![condition_statement.clone(), abort_statement.clone()];
        let mut symbol_table = HashMap::new();
        symbol_table.insert(
            make_identifier!("abc"),
            Symbol::Key("abc".to_string(), bind_library::ValueType::Number),
        );

        let instructions = compiler::compile_statements(statements, &symbol_table).unwrap();

        // Doesn't bind when abort statement is present.
        let properties =
            vec![Property { key: make_identifier!("abc"), value: Value::NumericLiteral(42) }];
        let mut debugger = Debugger::new(&properties, &instructions, &symbol_table).unwrap();
        assert!(!debugger.evaluate_bind_program().unwrap());
        assert_eq!(
            debugger.output,
            vec![
                DebuggerOutput::ConditionStatement {
                    statement: &condition_statement,
                    success: true
                },
                DebuggerOutput::AbortStatement { statement: &abort_statement }
            ]
        );
    }

    #[test]
    fn supports_all_value_types() {
        let statements = vec![
            Statement::ConditionStatement {
                span: Span::new(),
                condition: Condition {
                    span: Span::new(),
                    lhs: make_identifier!("a"),
                    op: ConditionOp::Equals,
                    rhs: Value::NumericLiteral(42),
                },
            },
            Statement::ConditionStatement {
                span: Span::new(),
                condition: Condition {
                    span: Span::new(),
                    lhs: make_identifier!("b"),
                    op: ConditionOp::Equals,
                    rhs: Value::BoolLiteral(false),
                },
            },
            Statement::ConditionStatement {
                span: Span::new(),
                condition: Condition {
                    span: Span::new(),
                    lhs: make_identifier!("c"),
                    op: ConditionOp::Equals,
                    rhs: Value::StringLiteral("string".to_string()),
                },
            },
            Statement::ConditionStatement {
                span: Span::new(),
                condition: Condition {
                    span: Span::new(),
                    lhs: make_identifier!("d"),
                    op: ConditionOp::Equals,
                    rhs: Value::Identifier(make_identifier!("VALUE")),
                },
            },
        ];
        let mut symbol_table = HashMap::new();
        symbol_table.insert(
            make_identifier!("a"),
            Symbol::Key("a".to_string(), bind_library::ValueType::Number),
        );
        symbol_table.insert(
            make_identifier!("b"),
            Symbol::Key("b".to_string(), bind_library::ValueType::Number),
        );
        symbol_table.insert(
            make_identifier!("c"),
            Symbol::Key("c".to_string(), bind_library::ValueType::Number),
        );
        symbol_table.insert(
            make_identifier!("d"),
            Symbol::Key("d".to_string(), bind_library::ValueType::Number),
        );
        symbol_table.insert(
            make_identifier!("VALUE"),
            Symbol::Key("VALUE".to_string(), bind_library::ValueType::Number),
        );

        let instructions = compiler::compile_statements(statements, &symbol_table).unwrap();

        // Binds when other properties are present as well.
        let properties = vec![
            Property { key: make_identifier!("a"), value: Value::NumericLiteral(42) },
            Property { key: make_identifier!("b"), value: Value::BoolLiteral(false) },
            Property {
                key: make_identifier!("c"),
                value: Value::StringLiteral("string".to_string()),
            },
            Property {
                key: make_identifier!("d"),
                value: Value::Identifier(make_identifier!("VALUE")),
            },
        ];
        let mut debugger = Debugger::new(&properties, &instructions, &symbol_table).unwrap();
        assert!(debugger.evaluate_bind_program().unwrap());
    }

    #[test]
    fn full_program() {
        /*
        if abc == 42 {
            abort;
        } else {
            accept xyz {1, 2};
            pqr != true;
        }
        */

        let condition = Condition {
            span: Span::new(),
            lhs: make_identifier!("abc"),
            op: ConditionOp::Equals,
            rhs: Value::NumericLiteral(42),
        };
        let abort_statement = Statement::Abort { span: Span::new() };
        let condition_statement = Statement::ConditionStatement {
            span: Span::new(),
            condition: Condition {
                span: Span::new(),
                lhs: make_identifier!("pqr"),
                op: ConditionOp::NotEquals,
                rhs: Value::BoolLiteral(true),
            },
        };

        let statements = vec![Statement::If {
            span: Span::new(),
            blocks: vec![(condition.clone(), vec![abort_statement.clone()])],
            else_block: vec![
                Statement::Accept {
                    span: Span::new(),
                    identifier: make_identifier!("xyz"),
                    values: vec![Value::NumericLiteral(1), Value::NumericLiteral(2)],
                },
                condition_statement.clone(),
            ],
        }];
        let mut symbol_table = HashMap::new();
        symbol_table.insert(
            make_identifier!("abc"),
            Symbol::Key("abc".to_string(), bind_library::ValueType::Number),
        );
        symbol_table.insert(
            make_identifier!("xyz"),
            Symbol::Key("xyz".to_string(), bind_library::ValueType::Number),
        );
        symbol_table.insert(
            make_identifier!("pqr"),
            Symbol::Key("pqr".to_string(), bind_library::ValueType::Number),
        );
        let instructions = compiler::compile_statements(statements, &symbol_table).unwrap();

        // Aborts because if condition is true.
        let properties =
            vec![Property { key: make_identifier!("abc"), value: Value::NumericLiteral(42) }];
        let mut debugger = Debugger::new(&properties, &instructions, &symbol_table).unwrap();
        assert!(!debugger.evaluate_bind_program().unwrap());
        assert_eq!(
            debugger.output,
            vec![
                DebuggerOutput::IfCondition { condition: &condition, success: true },
                DebuggerOutput::AbortStatement { statement: &abort_statement }
            ]
        );

        // Binds because all statements inside else block are satisfied.
        let properties = vec![
            Property { key: make_identifier!("abc"), value: Value::NumericLiteral(43) },
            Property { key: make_identifier!("xyz"), value: Value::NumericLiteral(1) },
        ];
        let mut debugger = Debugger::new(&properties, &instructions, &symbol_table).unwrap();
        assert!(debugger.evaluate_bind_program().unwrap());
        assert_eq!(
            debugger.output,
            vec![
                DebuggerOutput::IfCondition { condition: &condition, success: false },
                DebuggerOutput::AcceptStatementSuccess {
                    identifier: &make_identifier!("xyz"),
                    value: &Value::NumericLiteral(1),
                    value_symbol: &Symbol::NumberValue(1),
                    span: &Span::new(),
                },
                DebuggerOutput::ConditionStatement {
                    statement: &condition_statement,
                    success: true
                }
            ]
        );

        // Doesn't bind because accept statement is not satisfied.
        let properties = vec![
            Property { key: make_identifier!("abc"), value: Value::NumericLiteral(43) },
            Property { key: make_identifier!("xyz"), value: Value::NumericLiteral(3) },
        ];
        let mut debugger = Debugger::new(&properties, &instructions, &symbol_table).unwrap();
        assert!(!debugger.evaluate_bind_program().unwrap());
        assert_eq!(
            debugger.output,
            vec![
                DebuggerOutput::IfCondition { condition: &condition, success: false },
                DebuggerOutput::AcceptStatementFailure {
                    identifier: &make_identifier!("xyz"),
                    span: &Span::new(),
                },
            ]
        );

        // Doesn't bind because condition statement is not satisfied.
        let properties = vec![
            Property { key: make_identifier!("abc"), value: Value::NumericLiteral(43) },
            Property { key: make_identifier!("xyz"), value: Value::NumericLiteral(1) },
            Property { key: make_identifier!("pqr"), value: Value::BoolLiteral(true) },
        ];
        let mut debugger = Debugger::new(&properties, &instructions, &symbol_table).unwrap();
        assert!(!debugger.evaluate_bind_program().unwrap());
        assert_eq!(
            debugger.output,
            vec![
                DebuggerOutput::IfCondition { condition: &condition, success: false },
                DebuggerOutput::AcceptStatementSuccess {
                    identifier: &make_identifier!("xyz"),
                    value: &Value::NumericLiteral(1),
                    value_symbol: &Symbol::NumberValue(1),
                    span: &Span::new(),
                },
                DebuggerOutput::ConditionStatement {
                    statement: &condition_statement,
                    success: false
                }
            ]
        );
    }
}
