// Copyright 2023 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.

// NOTE: The doc comments on `IntetgrationTestCmd` and its fields appear as the helptext of
// `fx testgen`. Please run that command to make sure the output looks correct before
// submitting changes.

use crate::common::*;
use crate::flags;

use anyhow::{bail, Error};
use argh::FromArgs;
use std::path::PathBuf;
use tracing::info;

/// Generates an integration test for a Fuchsia component.
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "integration_test")]
pub(crate) struct IntegrationTestCmd {
    /// the absolute the path to the component-under-test's manifest.
    #[argh(option, short = 'm')]
    pub component_manifest: PathBuf,

    /// the absolute GN label of the fuchsia_component target under test. Example: //src/path/to:component.
    #[argh(option, short = 'l')]
    pub component_gn_label: String,

    /// the root directory where code will be generated. This directory must not exist.
    #[argh(option, short = 'o')]
    pub test_root: PathBuf,
}

/// Generates an integration test for a Fuchsia component.
///
/// Code is generated by copying the template files in templates/integration_test.
/// Each template uses the [handlebars](https://docs.rs/handlebars/latest/handlebars/) syntax.
///
/// Template variables:
///
///   component_name
///   component_exposed_protocols
///   component_gn_label
///   fidl_rust_crate_name
///   fidl_library_name
///   realm_factory_binary_name
///   rel_component_url
///   test_binary_name
///   test_package_name
///
/// See [`TemplateVars`] for the meaning of each variable.
impl IntegrationTestCmd {
    // TODO(127973): Add back support for C++
    pub async fn run(&self, _: &flags::Flags) -> Result<(), Error> {
        let test_root = self.test_root.clone();
        if test_root.exists() {
            bail!("{} already exists. Please choose a directory location that does not already exist.", test_root.display());
        }

        let component_manifest = self.component_manifest.clone();
        if !component_manifest.exists() {
            bail!("{} does not exist.", self.component_manifest.display());
        }
        if !component_manifest.extension().is_some_and(|x| x == "cml") {
            bail!("component manifest must be a .cml file");
        }

        let component_gn_label = self.component_gn_label.clone();
        if component_gn_label == "" {
            bail!("component_gn_label must not be empty");
        }
        if !component_gn_label.starts_with("//") {
            bail!("component_gn_label must be absolute and start with '//'")
        }

        info!("Generating an integration test at {}", test_root.display());

        // Initialize template variables and source code.
        let component_name = path_file_stem(&self.component_manifest);
        let cml = load_cml_file(&self.component_manifest)?;

        // rustfmt mangles this. long lines are easier to read.
        #[rustfmt::skip]
        let gen = CodeGenerator::new()
            .with_template_vars(TemplateVars{
                component_name: component_name.clone(),
                component_exposed_protocols: var_component_exposed_protocols(&cml),
                component_gn_label: self.component_gn_label.to_string(),
                rel_component_url: var_rel_component_url(&component_name),
                test_binary_name: var_test_binary_name(&component_name),
                test_package_name: var_test_package_name(&component_name),
                realm_factory_binary_name: var_realm_factory_binary_name(&component_name),
                fidl_rust_crate_name: var_fidl_rust_crate_name(&component_name),
                fidl_library_name: var_fidl_library_name(&component_name)
            })
            .with_template(hbrs_template_file!("integration_test", "tests/BUILD.gn"))
            .with_template(hbrs_template_file!("integration_test", "tests/meta/test-root.cml"))
            .with_template(hbrs_template_file!("integration_test", "tests/meta/test-suite.cml"))
            .with_template(hbrs_template_file!("integration_test", "tests/src/main.rs"))
            .with_template(hbrs_template_file!("integration_test", "testing/fidl/BUILD.gn"))
            .with_template(hbrs_template_file!("integration_test", "testing/fidl/realm_factory.test.fidl"))
            .with_template(hbrs_template_file!("integration_test", "testing/realm-factory/BUILD.gn"))
            .with_template(hbrs_template_file!("integration_test", "testing/realm-factory/meta/default.cml"))
            .with_template(hbrs_template_file!("integration_test", "testing/realm-factory/src/main.rs"));
        gen.generate(test_root)
    }
}
