// Copyright 2021 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::error::ComponentError, fidl_fuchsia_data as fdata, selectors::VerboseError,
    std::collections::BTreeMap,
};

#[derive(Debug)]
pub(crate) struct ProgramSpec {
    /// The name of the accessor to use.
    pub accessor: Accessor,

    /// The maximum amount of time to wait for this value to be present.
    pub timeout_seconds: i64,

    /// The test cases to execute.
    pub cases: BTreeMap<String, TestCase>,
}

impl ProgramSpec {
    /// Returns the list of test names from the program spec.
    pub fn test_names(&self) -> Vec<String> {
        self.cases.iter().map(|c| c.0.to_string()).collect()
    }
}

impl TryFrom<fdata::Dictionary> for ProgramSpec {
    type Error = ComponentError;

    fn try_from(dict: fdata::Dictionary) -> Result<Self, Self::Error> {
        let mut accessor = None;
        let mut timeout_seconds = None;
        let mut cases = None;

        for case in dict.entries.ok_or(ComponentError::MissingRequiredKey("program"))?.into_iter() {
            match case.key.as_ref() {
                "accessor" => {
                    accessor = match *case
                        .value
                        .ok_or(ComponentError::MissingRequiredKey("accessor"))?
                    {
                        fdata::DictionaryValue::Str(s) if s == "ALL" => Some(Accessor::All),
                        fdata::DictionaryValue::Str(s) if s == "FEEDBACK" => {
                            Some(Accessor::Feedback)
                        }
                        fdata::DictionaryValue::Str(s) if s == "LEGACY" => Some(Accessor::Legacy),
                        v => {
                            return Err(ComponentError::UnknownAccessorValue(format!("{:?}", v)));
                        }
                    }
                }
                "timeout_seconds" => {
                    if let fdata::DictionaryValue::Str(val) =
                        *case.value.ok_or(ComponentError::MissingRequiredKey("timeout_seconds"))?
                    {
                        timeout_seconds = Some(val.parse::<i64>().map_err(|_| {
                            ComponentError::WrongType("timeout_seconds", "numeric string")
                        })?);
                        if *timeout_seconds.as_ref().unwrap() <= 0 {
                            return Err(ComponentError::InvalidTimeout);
                        }
                    } else {
                        return Err(ComponentError::WrongType("timeout_seconds", "numeric string"));
                    }
                }
                "cases" => {
                    if let fdata::DictionaryValue::StrVec(val) =
                        *case.value.ok_or(ComponentError::MissingRequiredKey("cases"))?
                    {
                        let items: Result<Vec<TestCase>, _> =
                            val.into_iter().map(|v| TestCase::try_from(v)).collect();
                        cases = Some(items?);
                    } else {
                        return Err(ComponentError::WrongType("cases", "string array"));
                    }
                }
                k => {
                    return Err(ComponentError::UnknownKey(k.to_string()));
                }
            }
        }

        match (accessor, timeout_seconds, cases) {
            (Some(accessor), Some(timeout_seconds), Some(cases)) => {
                let cases: BTreeMap<String, TestCase> =
                    cases.into_iter().map(|c| (c.key.clone(), c)).collect();

                Ok(ProgramSpec { accessor, timeout_seconds, cases })
            }
            (None, _, _) => Err(ComponentError::MissingRequiredKey("accessor")),
            (_, None, _) => Err(ComponentError::MissingRequiredKey("timeout_seconds")),
            (_, _, None) => Err(ComponentError::MissingRequiredKey("cases")),
        }
    }
}

#[derive(Debug, PartialEq)]
pub(crate) enum Accessor {
    All,
    Feedback,
    Legacy,
}

#[derive(Debug, PartialEq)]
pub(crate) struct TestCase {
    /// The unique key for this test case inside this suite.
    pub key: String,

    /// The selector that will be used to read from the Archivist for this test case.
    pub selector: String,

    /// If set, this triage expression is applied against the value returned by the selector.
    /// Otherwise, the test passes so long as any value is selected.
    pub expression: Option<String>,
}

impl std::string::ToString for TestCase {
    fn to_string(&self) -> String {
        self.key.clone()
    }
}

impl TryFrom<String> for TestCase {
    type Error = ComponentError;
    fn try_from(value: String) -> Result<Self, Self::Error> {
        let splits: Vec<&str> = value.split(" WHERE ").collect();
        if splits.len() == 1 {
            let selector = splits[0].to_string();
            selectors::parse_selector::<VerboseError>(&selector).map_err(|e| {
                ComponentError::InvalidTestCase { value: value.clone(), reason: e.to_string() }
            })?;
            Ok(TestCase { key: value, selector, expression: None })
        } else if splits.len() == 2 {
            let selector = splits[0].to_string();
            let expression = Some(splits[1].to_string());
            selectors::parse_selector::<VerboseError>(&selector).map_err(|e| {
                ComponentError::InvalidTestCase { value: value.clone(), reason: e.to_string() }
            })?;
            Ok(TestCase { key: value, selector, expression })
        } else {
            Err(ComponentError::InvalidTestCase {
                value,
                reason: "too many 'WHERE' clauses".to_string(),
            })
        }
    }
}

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

    #[derive(Clone, Debug)]
    struct DictBuilder {
        accessor: Option<String>,
        timeout_seconds: Option<String>,
        cases: Vec<String>,
    }

    impl DictBuilder {
        fn new() -> Self {
            DictBuilder { accessor: None, timeout_seconds: None, cases: vec![] }
        }

        fn with_accessor(mut self, value: impl Into<String>) -> Self {
            self.accessor = Some(value.into());
            self
        }

        fn with_timeout_seconds(mut self, value: impl Into<String>) -> Self {
            self.timeout_seconds = Some(value.into());
            self
        }

        fn add_case(mut self, value: impl Into<String>) -> Self {
            self.cases.push(value.into());
            self
        }

        fn build(self) -> fdata::Dictionary {
            let mut ret = fdata::Dictionary { entries: Some(vec![]), ..Default::default() };

            let mut add_value = |key: &str, value: fdata::DictionaryValue| {
                ret.entries.as_mut().expect("entries exists").push(fdata::DictionaryEntry {
                    key: key.to_string(),
                    value: Some(Box::new(value)),
                });
            };

            if let Some(val) = self.accessor {
                add_value("accessor", fdata::DictionaryValue::Str(val));
            }
            if let Some(val) = self.timeout_seconds {
                add_value("timeout_seconds", fdata::DictionaryValue::Str(val));
            }
            if self.cases.len() > 0 {
                add_value("cases", fdata::DictionaryValue::StrVec(self.cases));
            }

            ret
        }
    }

    #[test]
    fn empty_dictionary_fails() {
        assert_eq!(
            ComponentError::MissingRequiredKey("program"),
            ProgramSpec::try_from(fdata::Dictionary::default()).unwrap_err()
        );
    }

    #[test]
    fn fields_are_present() {
        assert_eq!(
            ComponentError::MissingRequiredKey("accessor"),
            ProgramSpec::try_from(DictBuilder::new().build()).unwrap_err(),
        );
        assert_eq!(
            ComponentError::MissingRequiredKey("timeout_seconds"),
            ProgramSpec::try_from(DictBuilder::new().with_accessor("ALL").build()).unwrap_err(),
        );
        assert_eq!(
            ComponentError::MissingRequiredKey("cases"),
            ProgramSpec::try_from(
                DictBuilder::new().with_accessor("ALL").with_timeout_seconds("10").build()
            )
            .unwrap_err(),
        );
        assert!(ProgramSpec::try_from(
            DictBuilder::new()
                .with_accessor("ALL")
                .with_timeout_seconds("10")
                .add_case("a:b:c")
                .build()
        )
        .is_ok());
    }

    #[test]
    fn accessor_validation() {
        let base_dict = DictBuilder::new().with_timeout_seconds("10").add_case("a:b:c");
        assert_eq!(
            ComponentError::UnknownAccessorValue("Str(\"SOMETHING\")".to_string()),
            ProgramSpec::try_from(base_dict.clone().with_accessor("SOMETHING").build())
                .unwrap_err(),
        );
        for (name, value) in vec![
            ("ALL", Accessor::All),
            ("FEEDBACK", Accessor::Feedback),
            ("LEGACY", Accessor::Legacy),
        ] {
            let spec = ProgramSpec::try_from(base_dict.clone().with_accessor(name).build())
                .expect("validate accessor");
            assert_eq!(spec.accessor, value);
        }
    }

    #[test]
    fn timeout_seconds_validation() {
        let base_dict = DictBuilder::new().with_accessor("ALL").add_case("a:b:c");
        assert_eq!(
            ComponentError::WrongType("timeout_seconds", "numeric string"),
            ProgramSpec::try_from(base_dict.clone().with_timeout_seconds("invalid").build())
                .unwrap_err()
        );
        let spec = ProgramSpec::try_from(base_dict.clone().with_timeout_seconds("100").build())
            .expect("validate timeout_seconds");
        assert_eq!(spec.timeout_seconds, 100);
    }

    #[test]
    fn test_case_validation() {
        let base_dict = DictBuilder::new().with_accessor("ALL").with_timeout_seconds("10");
        assert_eq!(
            ComponentError::InvalidTestCase {
                value: "a WHERE b WHERE c".to_string(),
                reason: "too many 'WHERE' clauses".to_string(),
            },
            ProgramSpec::try_from(base_dict.clone().add_case("a WHERE b WHERE c").build())
                .unwrap_err()
        );

        // Test that selector parsing catches invalid selectors.
        assert!(ProgramSpec::try_from(base_dict.clone().add_case("a:b:c:d").build()).is_err());
        assert!(ProgramSpec::try_from(base_dict.clone().add_case("a").build()).is_err());

        let spec = ProgramSpec::try_from(
            base_dict.clone().add_case("a:b:c").add_case("a:b:c WHERE [d] d > 0").build(),
        )
        .expect("validate cases");
        assert_eq!(
            spec.cases["a:b:c"],
            TestCase { key: "a:b:c".to_string(), selector: "a:b:c".to_string(), expression: None }
        );
        assert_eq!(
            spec.cases["a:b:c WHERE [d] d > 0"],
            TestCase {
                key: "a:b:c WHERE [d] d > 0".to_string(),
                selector: "a:b:c".to_string(),
                expression: Some("[d] d > 0".to_string())
            }
        );
    }
}
