// Copyright 2020 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::compiler,
    crate::device_specification::DeviceSpecification,
    crate::errors::UserError,
    crate::offline_debugger::{self, debug_from_device_specification},
    crate::parser_common,
    serde::Deserialize,
    serde_json,
    std::collections::HashMap,
    std::convert::TryFrom,
    std::fmt,
    thiserror::Error,
    valico::json_schema,
};

const SCHEMA: &str = include_str!("../tests_schema.json");

#[derive(Deserialize, Debug, PartialEq)]
#[serde(rename_all = "lowercase")]
enum ExpectedResult {
    Match,
    Abort,
}

#[derive(Deserialize, Debug)]
pub struct TestSpec {
    name: String,
    expected: ExpectedResult,
    device: HashMap<String, String>,
}

struct TestSuite {
    specs: Vec<TestSpec>,
}

#[derive(Debug, Error, Clone, PartialEq)]
pub enum TestError {
    BindParserError(parser_common::BindParserError),
    DeviceSpecParserError(parser_common::BindParserError),
    DebuggerError(offline_debugger::DebuggerError),
    CompilerError(compiler::CompilerError),
    InvalidSchema,
    JsonParserError(String),
    // The JSON validator unfortunately doesn't produce useful error messages.
    InvalidJsonError,
}

pub fn run(program: &str, libraries: &[String], tests: &str) -> Result<bool, TestError> {
    TestSuite::try_from(tests).and_then(|t| t.run(program, libraries))
}

impl TestSuite {
    fn run(&self, program: &str, libraries: &[String]) -> Result<bool, TestError> {
        let (instructions, symbol_table) =
            compiler::compile_to_symbolic(program, libraries).map_err(TestError::CompilerError)?;

        for test in &self.specs {
            let mut device_specification = DeviceSpecification::new();
            for (key, value) in &test.device {
                device_specification
                    .add_property(&key, &value)
                    .map_err(TestError::DeviceSpecParserError)?;
            }

            let result =
                debug_from_device_specification(&instructions, &symbol_table, device_specification)
                    .map_err(TestError::DebuggerError)?;
            match (&test.expected, result) {
                (ExpectedResult::Match, false) => return Ok(false),
                (ExpectedResult::Abort, true) => return Ok(false),
                _ => (),
            }
        }

        Ok(true)
    }
}

impl TryFrom<&str> for TestSuite {
    type Error = TestError;

    fn try_from(input: &str) -> Result<Self, Self::Error> {
        let schema = serde_json::from_str(&SCHEMA)
            .map_err(|e| TestError::JsonParserError(format!("{}", e)))?;
        let mut scope = json_schema::Scope::new();
        let compiled_schema =
            scope.compile_and_return(schema, false).map_err(|_| TestError::InvalidSchema)?;

        let spec = serde_json::from_str(input)
            .map_err(|e| TestError::JsonParserError(format!("{}", e)))?;

        let res = compiled_schema.validate(&spec);
        if !res.is_strictly_valid() {
            return Err(TestError::InvalidJsonError);
        }

        let specs: Vec<TestSpec> = serde_json::from_value(spec)
            .map_err(|e| TestError::JsonParserError(format!("{}", e)))?;
        Ok(TestSuite { specs })
    }
}

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

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn parse_one_test() {
        let TestSuite { specs } = TestSuite::try_from(
            r#"
[
    {
        "name": "A test",
        "expected": "match",
        "device": {
            "key": "value"
        }
    }
]"#,
        )
        .unwrap();
        assert_eq!(specs.len(), 1);
        assert_eq!(specs[0].name, "A test".to_string());
        assert_eq!(specs[0].expected, ExpectedResult::Match);

        let mut expected_device = HashMap::new();
        expected_device.insert("key".to_string(), "value".to_string());
        assert_eq!(specs[0].device, expected_device);
    }

    #[test]
    fn parse_two_tests() {
        let TestSuite { specs } = TestSuite::try_from(
            r#"
[
    {
        "name": "A test",
        "expected": "match",
        "device": {
            "key": "value"
        }
    },
    {
        "name": "A second test",
        "expected": "abort",
        "device": {
            "key1": "value1",
            "key2": "value2"
        }
    }
]"#,
        )
        .unwrap();
        assert_eq!(specs.len(), 2);
        assert_eq!(specs[0].name, "A test".to_string());
        assert_eq!(specs[0].expected, ExpectedResult::Match);
        assert_eq!(specs[1].name, "A second test".to_string());
        assert_eq!(specs[1].expected, ExpectedResult::Abort);

        let mut expected_device = HashMap::new();
        expected_device.insert("key".to_string(), "value".to_string());
        assert_eq!(specs[0].device, expected_device);

        let mut expected_device2 = HashMap::new();
        expected_device2.insert("key1".to_string(), "value1".to_string());
        expected_device2.insert("key2".to_string(), "value2".to_string());
        assert_eq!(specs[1].device, expected_device2);
    }

    #[test]
    fn parse_json_failure() {
        match TestSuite::try_from("this can't be parsed") {
            Err(TestError::JsonParserError(_)) => (),
            _ => panic!("Expected a JsonParserError"),
        }
    }

    #[test]
    fn parse_invalid_json() {
        match TestSuite::try_from(r#"{ "valid json": "invalid to spec" }"#) {
            Err(TestError::InvalidJsonError) => (),
            _ => panic!("Expected a InvalidJsonError"),
        };
    }
}
