// 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 {
    super::{
        data::Data,
        puppet, results,
        trials::{self, Step},
        validate,
    },
    anyhow::{bail, Error},
    diagnostics_reader::{ArchiveReader, ComponentSelector, Inspect},
    fidl_test_inspect_validate::TestResult,
};

pub async fn run_all_trials(url: &str, results: &mut results::Results) {
    let mut trial_set = trials::real_trials();
    for trial in trial_set.iter_mut() {
        match puppet::Puppet::connect(url).await {
            Ok(mut puppet) => {
                if results.test_archive {
                    match puppet.publish().await {
                        Ok(TestResult::Ok) => {}
                        Ok(result) => {
                            results.error(format!("Publish reported {:?}", result));
                            return;
                        }
                        Err(e) => {
                            results.error(format!("Publish error: {:?}", e));
                            return;
                        }
                    }
                }
                let mut data = Data::new();
                if let Err(e) = run_trial(&mut puppet, &mut data, trial, results).await {
                    results.error(format!("Running trial {}, got failure:\n{}", trial.name, e));
                } else {
                    results.log(format!("Trial {} succeeds", trial.name));
                }
                if results.test_archive {
                    match puppet.unpublish().await {
                        Ok(TestResult::Ok) => {}
                        Ok(result) => {
                            results.error(format!("Unpublish reported {:?}", result));
                            return;
                        }
                        Err(e) => {
                            results.error(format!("Unpublish error: {:?}", e));
                            return;
                        }
                    }
                }
            }
            Err(e) => {
                results.error(format!(
                    "Failed to form Puppet - error {:?} - URL may be invalid: {}.",
                    e, url
                ));
            }
        }
    }
}

#[derive(PartialEq)]
enum StepResult {
    // Signals that we should continue with the next step.
    Continue,
    // Signals that the state after executing this step is inconsistent, we should stop running
    // further steps.
    Stop,
}

async fn run_trial(
    puppet: &mut puppet::Puppet,
    data: &mut Data,
    trial: &mut trials::Trial,
    results: &mut results::Results,
) -> Result<(), Error> {
    let trial_name = format!("{}:{}", puppet.name(), trial.name);
    // We have to give explicit type here because compiler can't deduce it from None option value.
    try_compare::<validate::Action>(data, puppet, &trial_name, -1, None, -1, &results).await?;
    for (step_index, step) in trial.steps.iter_mut().enumerate() {
        let step_result = match step {
            Step::Actions(actions) => {
                run_actions(actions, data, puppet, &trial.name, step_index, results).await?
            }
            Step::WithMetrics(actions, step_name) => {
                let r =
                    run_actions(actions, data, puppet, &trial.name, step_index, results).await?;
                results.remember_metrics(puppet.metrics()?, &trial.name, step_index, step_name);
                r
            }
            Step::LazyActions(actions) => {
                run_lazy_actions(actions, data, puppet, &trial.name, step_index, results).await?
            }
        };
        if step_result == StepResult::Stop {
            break;
        }
    }
    Ok(())
}

async fn run_actions(
    actions: &mut Vec<validate::Action>,
    data: &mut Data,
    puppet: &mut puppet::Puppet,
    trial_name: &str,
    step_index: usize,
    results: &mut results::Results,
) -> Result<StepResult, Error> {
    for (action_number, action) in actions.iter_mut().enumerate() {
        if let Err(e) = data.apply(action) {
            bail!(
                "Local-apply error in trial {}, step {}, action {}: {:?} ",
                trial_name,
                step_index,
                action_number,
                e
            );
        }
        match puppet.apply(action).await {
            Err(e) => {
                bail!(
                    "Puppet-apply error in trial {}, step {}, action {}: {:?} ",
                    trial_name,
                    step_index,
                    action_number,
                    e
                );
            }
            Ok(validate::TestResult::Ok) => {}
            Ok(validate::TestResult::Unimplemented) => {
                results.unimplemented(puppet.name(), action);
                return Ok(StepResult::Stop);
            }
            Ok(bad_result) => {
                bail!(
                    "In trial {}, puppet {} reported action {:?} was {:?}",
                    trial_name,
                    puppet.name(),
                    action,
                    bad_result
                );
            }
        }
        try_compare(
            data,
            puppet,
            &trial_name,
            step_index as i32,
            Some(action),
            action_number as i32,
            &results,
        )
        .await?;
    }
    Ok(StepResult::Continue)
}

async fn run_lazy_actions(
    actions: &mut Vec<validate::LazyAction>,
    data: &mut Data,
    puppet: &mut puppet::Puppet,
    trial_name: &str,
    step_index: usize,
    results: &mut results::Results,
) -> Result<StepResult, Error> {
    for (action_number, action) in actions.iter_mut().enumerate() {
        if let Err(e) = data.apply_lazy(action) {
            bail!(
                "Local-apply_lazy error in trial {}, step {}, action {}: {:?} ",
                trial_name,
                step_index,
                action_number,
                e
            );
        }
        match puppet.apply_lazy(action).await {
            Err(e) => {
                bail!(
                    "Puppet-apply_lazy error in trial {}, step {}, action {}: {:?} ",
                    trial_name,
                    step_index,
                    action_number,
                    e
                );
            }
            Ok(validate::TestResult::Ok) => {}
            Ok(validate::TestResult::Unimplemented) => {
                results.unimplemented(puppet.name(), action);
                return Ok(StepResult::Stop);
            }
            Ok(bad_result) => {
                bail!(
                    "In trial {}, puppet {} reported action {:?} was {:?}",
                    trial_name,
                    puppet.name(),
                    action,
                    bad_result
                );
            }
        }
        try_compare(
            data,
            puppet,
            &trial_name,
            step_index as i32,
            Some(action),
            action_number as i32,
            &results,
        )
        .await?;
    }
    Ok(StepResult::Continue)
}

async fn try_compare<ActionType: std::fmt::Debug>(
    data: &Data,
    puppet: &puppet::Puppet,
    trial_name: &str,
    step_index: i32,
    action: Option<&ActionType>,
    action_number: i32,
    results: &results::Results,
) -> Result<(), Error> {
    if !data.is_empty() {
        match puppet.read_data().await {
            Err(e) => {
                bail!(
                    "Puppet-read error in trial {}, step {}, action {} {:?}: {:?} ",
                    trial_name,
                    step_index,
                    action_number,
                    action,
                    e
                );
            }
            Ok(puppet_data) => {
                if let Err(e) = data.compare(&puppet_data, results.diff_type) {
                    bail!(
                        "Compare error in trial {}, step {}, action {}:\n{:?}:\n{} ",
                        trial_name,
                        step_index,
                        action_number,
                        action,
                        e
                    );
                }
            }
        }
        if results.test_archive {
            let archive_data = match ArchiveReader::new()
                .add_selector(ComponentSelector::new(vec![
                    puppet.environment_name().to_string(),
                    puppet.component_name(),
                ]))
                .add_selector(
                    ComponentSelector::new(vec![
                        puppet.environment_name().to_string(),
                        puppet.component_name(),
                    ])
                    .with_tree_selector("root:DUMMY"),
                )
                .snapshot::<Inspect>()
                .await
            {
                Ok(archive_data) => archive_data,
                Err(e) => {
                    bail!(
                        "Archive read error in trial {}, step {}, action {}:\n{:?}:\n{} ",
                        trial_name,
                        step_index,
                        action_number,
                        action,
                        e
                    );
                }
            };

            if archive_data.len() != 1 {
                bail!(
                    "Expected 1 component in trial {}, step {}, action {}:\n{:?}:\nfound {} ",
                    trial_name,
                    step_index,
                    action_number,
                    action,
                    archive_data.len()
                );
            }

            let hierarchy = archive_data[0].payload.as_ref().unwrap();
            if let Err(e) = data.compare_to_json(&hierarchy.clone().into(), results.diff_type) {
                bail!(
                    "Archive compare error in trial {}, step {}, action {}:\n{:?}:\n{} ",
                    trial_name,
                    step_index,
                    action_number,
                    action,
                    e
                );
            }
        }
    }
    Ok(())
}

#[cfg(test)]
mod tests {
    use {
        super::*,
        crate::trials::tests::trial_with_action,
        crate::trials::{Step, Trial},
        crate::*,
        fidl_test_inspect_validate::*,
        fuchsia_async as fasync,
    };

    #[fasync::run_singlethreaded(test)]
    async fn unimplemented_works() -> Result<(), Error> {
        let mut int_maker = trial_with_action(
            "foo",
            create_numeric_property!(
            parent: ROOT_ID, id: 1, name: "int", value: Number::IntT(0)),
        );
        let mut uint_maker = trial_with_action(
            "foo",
            create_numeric_property!(
            parent: ROOT_ID, id: 2, name: "uint", value: Number::UintT(0)),
        );
        let mut uint_create_delete = Trial {
            name: "foo".to_string(),
            steps: vec![
                Step::Actions(vec![
                    create_numeric_property!(parent: ROOT_ID, id: 2, name: "uint", value: Number::UintT(0)),
                ]),
                Step::Actions(vec![delete_property!(id: 2)]),
            ],
        };
        let mut results = results::Results::new();
        let mut puppet = puppet::tests::local_incomplete_puppet().await?;
        // results contains a list of the _un_implemented actions. local_incomplete_puppet()
        // implements Int creation, but not Uint. So results should not include Uint but should
        // include Int.
        {
            let mut data = Data::new();
            run_trial(&mut puppet, &mut data, &mut int_maker, &mut results).await?;
        }
        {
            let mut data = Data::new();
            run_trial(&mut puppet, &mut data, &mut uint_maker, &mut results).await?;
        }
        {
            let mut data = Data::new();
            run_trial(&mut puppet, &mut data, &mut uint_create_delete, &mut results).await?;
        }
        assert!(!results.to_json().contains(&format!("{}: CreateProperty(Int)", puppet.name())));
        assert!(results.to_json().contains(&format!("{}: CreateProperty(Uint)", puppet.name())));
        Ok(())
    }
}
