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

//! This file contains "golden" tests, which compare the output of known sample
//! `Cargo.toml` files with known fixed reference output files.
//!
//! TODO(https://fxbug.dev/42178193) move these golden specs into GN

use {
    anyhow::Context,
    argh::FromArgs,
    // Without this, the test diffs are impractical to debug.
    pretty_assertions::assert_eq,
    std::fmt::{Debug, Display},
    std::path::{Path, PathBuf},
};

#[derive(FromArgs, Debug)]
/// Paths to use in test. All paths are relative to where this test is executed.
///
/// These paths have to be relative when passed to this test on infra bots, so they are mapped
/// correctly, otherwise they won't be available at test runtime. It is safe to convert these to
/// absolute paths later in the test.
struct Paths {
    /// path to the directory where golden tests are placed.
    #[argh(option)]
    test_base_dir: String,
    /// path to `rustc` binary to use in test.
    #[argh(option)]
    rustc_binary_path: String,
    /// path to `gn` binary to use in test.
    #[argh(option)]
    gn_binary_path: String,
    /// path to `cargo` binary to use in test.
    #[argh(option)]
    cargo_binary_path: String,
    /// path to shared libraries directory to use in test.
    #[argh(option)]
    lib_path: String,
}

#[derive(PartialEq, Eq)]
struct DisplayAsDebug<T: Display>(T);

impl<T: Display> Debug for DisplayAsDebug<T> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        Display::fmt(&self.0, f)
    }
}

fn main() {
    let paths: Paths = argh::from_env();
    eprintln!("paths: {:?}", &paths);

    // Shared library setup for Linux and Mac.  Systems will ignore the settings
    // that don't apply to them.
    //
    // These values need to be absolute so they work regardless of the current working directory.
    std::env::set_var("LD_LIBRARY_PATH", Path::new(&paths.lib_path).canonicalize().unwrap());
    std::env::set_var("DYLD_LIBRARY_PATH", Path::new(&paths.lib_path).canonicalize().unwrap());

    // Cargo internally invokes rustc; but we must tell it to use the one from
    // our sandbox, and this is configured using the env variable "RUSTC".
    //
    // This value needs to be absolute so it works regardless of the current working directory.
    //
    // See:
    // https://doc.rust-lang.org/cargo/reference/environment-variables.html
    std::env::set_var("RUSTC", Path::new(&paths.rustc_binary_path).canonicalize().unwrap());

    #[derive(Debug, Default)]
    struct Options {
        /// Fuchsia SDK metadata output path; relative to the base test directory.
        sdk_metadata_path: Option<Vec<&'static str>>,
        /// Fuchsia SDK metadata golden path; relative to the golden files directory.
        sdk_metadata_golden_path: Option<Vec<&'static str>>,
        /// Extra arguments to pass to gnaw.
        extra_args: Vec<&'static str>,
    }
    #[derive(Debug)]
    struct TestCase {
        /// Manifest file path (`Cargo.toml`); relative to the base test directory.
        manifest_path: Vec<&'static str>,
        /// Expected file (`BUILD.gn`); relative to the base test directory.
        golden_expected_filename: Vec<&'static str>,
        /// Extra stuff not needed for most tests.
        options: Options,
    }

    let tests = vec![
        TestCase {
            manifest_path: vec!["simple", "Cargo.toml"],
            golden_expected_filename: vec!["simple", "BUILD.gn"],
            options: Default::default(),
        },
        TestCase {
            manifest_path: vec!["simple_deps", "Cargo.toml"],
            golden_expected_filename: vec!["simple_deps", "BUILD.gn"],
            options: Default::default(),
        },
        TestCase {
            manifest_path: vec!["simple_deps", "Cargo.toml"],
            golden_expected_filename: vec!["simple_deps", "BUILD_WITH_NO_ROOT.gn"],
            options: Options { extra_args: vec!["--skip-root"], ..Default::default() },
        },
        TestCase {
            manifest_path: vec!["platform_deps", "Cargo.toml"],
            golden_expected_filename: vec!["platform_deps", "BUILD.gn"],
            options: Options { extra_args: vec!["--skip-root"], ..Default::default() },
        },
        TestCase {
            manifest_path: vec!["platform_features", "Cargo.toml"],
            golden_expected_filename: vec!["platform_features", "BUILD.gn"],
            options: Options { extra_args: vec!["--skip-root"], ..Default::default() },
        },
        TestCase {
            manifest_path: vec!["binary", "Cargo.toml"],
            golden_expected_filename: vec!["binary", "BUILD.gn"],
            options: Default::default(),
        },
        TestCase {
            manifest_path: vec!["binary_with_tests", "Cargo.toml"],
            golden_expected_filename: vec!["binary_with_tests", "BUILD.gn"],
            options: Default::default(),
        },
        TestCase {
            manifest_path: vec!["multiple_crate_types", "Cargo.toml"],
            golden_expected_filename: vec!["multiple_crate_types", "BUILD.gn"],
            options: Default::default(),
        },
        TestCase {
            manifest_path: vec!["feature_review", "Cargo.toml"],
            golden_expected_filename: vec!["feature_review", "BUILD.gn"],
            options: Default::default(),
        },
        TestCase {
            manifest_path: vec!["cargo_features", "Cargo.toml"],
            golden_expected_filename: vec!["cargo_features", "BUILD-default.gn"],
            options: Default::default(),
        },
        TestCase {
            manifest_path: vec!["cargo_features", "Cargo.toml"],
            golden_expected_filename: vec!["cargo_features", "BUILD-all-features.gn"],
            options: Options { extra_args: vec!["--all-features"], ..Default::default() },
        },
        TestCase {
            manifest_path: vec!["cargo_features", "Cargo.toml"],
            golden_expected_filename: vec!["cargo_features", "BUILD-no-default-features.gn"],
            options: Options { extra_args: vec!["--no-default-features"], ..Default::default() },
        },
        TestCase {
            manifest_path: vec!["cargo_features", "Cargo.toml"],
            golden_expected_filename: vec!["cargo_features", "BUILD-featurefoo.gn"],
            options: Options { extra_args: vec!["--features", "featurefoo"], ..Default::default() },
        },
        TestCase {
            manifest_path: vec!["visibility", "Cargo.toml"],
            golden_expected_filename: vec!["visibility", "BUILD.gn"],
            options: Options { extra_args: vec!["--skip-root"], ..Default::default() },
        },
        TestCase {
            manifest_path: vec!["target_renaming", "Cargo.toml"],
            golden_expected_filename: vec!["target_renaming", "BUILD.gn"],
            options: Options { extra_args: vec!["--skip-root"], ..Default::default() },
        },
        TestCase {
            manifest_path: vec!["sdk_metadata", "Cargo.toml"],
            golden_expected_filename: vec!["sdk_metadata", "BUILD.gn"],
            options: Options {
                sdk_metadata_path: Some(vec!["sdk_metas", "sdk_metadata.sdk.meta.json"]),
                sdk_metadata_golden_path: Some(vec![
                    "sdk_metadata",
                    "sdk_metas",
                    "sdk_metadata.sdk.meta.json",
                ]),
                ..Default::default()
            },
        },
        TestCase {
            manifest_path: vec!["testonly", "Cargo.toml"],
            golden_expected_filename: vec!["testonly", "BUILD.gn"],
            options: Options { extra_args: vec!["--skip-root"], ..Default::default() },
        },
    ];

    let run_gnaw = |manifest_path: &[&str],
                    extra_args: &[&str],
                    sdk_metadata_path: Option<&[&str]>| {
        let test_dir = tempfile::TempDir::new().unwrap();
        let mut manifest_path: PathBuf =
            test_dir.path().join(manifest_path.iter().collect::<PathBuf>());
        let output = test_dir.path().join("BUILD.gn");
        let output_sdk_metadata = sdk_metadata_path.map(|sdk_metadata_path| {
            test_dir.path().join(sdk_metadata_path.iter().collect::<PathBuf>())
        });

        // we need the emitted file to be under the same path as the gn targets it references
        let test_base_dir = PathBuf::from(&paths.test_base_dir);
        copy_contents(&test_base_dir, test_dir.path());

        if manifest_path.file_name().unwrap() != "Cargo.toml" {
            // rename manifest so that `cargo metadata` is happy.
            let manifest_dest_path =
                manifest_path.parent().expect("getting Cargo.toml parent dir").join("Cargo.toml");
            std::fs::copy(&manifest_path, &manifest_dest_path).expect("writing Cargo.toml");
            manifest_path = manifest_dest_path;
        }

        let project_root = test_dir.path().to_str().unwrap().to_owned();
        // Note: argh does not support "--flag=value" or "--bool-flag false".
        let absolute_cargo_binary_path =
            Path::new(&paths.cargo_binary_path).canonicalize().unwrap();
        let mut args: Vec<&str> = vec![
            // args[0] is not used in arg parsing, so this can be any string.
            "fake_binary_name",
            "--manifest-path",
            manifest_path.to_str().unwrap(),
            "--project-root",
            &project_root,
            "--output",
            output.to_str().unwrap(),
            "--gn-bin",
            &paths.gn_binary_path,
            "--cargo",
            // Cargo is not executed in another working directory by gnaw_lib, so an absolute path
            // is necessary here.
            absolute_cargo_binary_path.to_str().unwrap(),
        ];
        if let Some(output_sdk_metadata) = &output_sdk_metadata {
            args.extend(&[
                "--output-fuchsia-sdk-metadata",
                output_sdk_metadata.parent().unwrap().to_str().unwrap(),
            ]);
        }
        args.extend(extra_args);
        gnaw_lib::run(&args)
            .with_context(|| format!("error running gnaw with args: {:?}\n\t", &args))?;
        let output = std::fs::read_to_string(&output)
            .with_context(|| format!("while reading tempfile: {}", output.display()))
            .expect("tempfile read success");
        let output_sdk_metadata = output_sdk_metadata
            .as_ref()
            .map(std::fs::read_to_string)
            .transpose()
            .with_context(|| {
                format!("while reading sdk metadata: {}", output_sdk_metadata.unwrap().display())
            })
            .expect("sdk metadata read success");
        Result::<_, anyhow::Error>::Ok((output, output_sdk_metadata))
    };

    for test in tests {
        let (output, output_sdk_metadata) = run_gnaw(
            &test.manifest_path,
            &test.options.extra_args,
            test.options.sdk_metadata_path.as_deref(),
        )
        .with_context(|| format!("\n\ttest was: {:?}", &test))
        .expect("gnaw_lib::run should succeed");

        let test_base_dir = PathBuf::from(&paths.test_base_dir);
        let expected_path: PathBuf =
            test_base_dir.join(test.golden_expected_filename.iter().collect::<PathBuf>());
        let expected = std::fs::read_to_string(expected_path.to_string_lossy().to_string())
            .with_context(|| {
                format!("while reading expected: {:?}", &test.golden_expected_filename)
            })
            .expect("expected file read success");
        assert_eq!(
            DisplayAsDebug(&expected),
            DisplayAsDebug(&output),
            "left: expected; right: actual: {:?}\n\nGenerated content:\n----------\n{}\n----------\n",
            &test,
            &output
        );

        if let Some(output_sdk_metadata) = output_sdk_metadata {
            let expected_sdk_metadata_path = test_base_dir.join(
                test.options.sdk_metadata_golden_path.as_ref().unwrap().iter().collect::<PathBuf>(),
            );
            let expected_sdk_metadata = std::fs::read_to_string(&expected_sdk_metadata_path)
                .with_context(|| {
                    format!("while reading sdk metadata: {}", expected_sdk_metadata_path.display())
                })
                .expect("sdk metadata read success");
            assert_eq!(
                DisplayAsDebug(&expected_sdk_metadata),
                DisplayAsDebug(&output_sdk_metadata),
                "left: expected; right: actual: {:?}\n\nGenerated content:\n----------\n{}\n----------\n",
                &test,
                &output_sdk_metadata,
            );
        }
    }

    #[derive(Debug)]
    struct ExpectFailCase {
        /// Manifest file path (`Cargo.toml`); relative to the base test directory.
        manifest_path: Vec<&'static str>,
        /// Expected string to search for in returned error.
        expected_error_substring: &'static str,
        /// Extra arguments to pass to gnaw.
        extra_args: Vec<&'static str>,
    }
    let tests = vec![
        ExpectFailCase {
            manifest_path: vec!["feature_review", "Cargo_unreviewed_feature.toml"],
            expected_error_substring:
                "crate_with_features 0.1.0 is included with unreviewed features [\"feature1\"]",
            extra_args: vec![],
        },
        ExpectFailCase {
            manifest_path: vec!["feature_review", "Cargo_missing_review.toml"],
            expected_error_substring:
                "crate_with_features 0.1.0 requires feature review but reviewed features not found",
            extra_args: vec![],
        },
        ExpectFailCase {
            manifest_path: vec!["feature_review", "Cargo_extra_review.toml"],
            expected_error_substring:
                "crate_with_features 0.1.0 sets reviewed_features but crate_with_features was not found in require_feature_reviews",
            extra_args: vec![],
        },
    ];
    for test in tests {
        let result = run_gnaw(&test.manifest_path, &test.extra_args, None);
        let error = match result {
            Ok(_) => panic!("gnaw unexpectedly succeeded for {:?}", test),
            Err(e) => e,
        };
        if error.chain().find(|e| e.to_string().contains(test.expected_error_substring)).is_none() {
            panic!(
                "expected error to contain {:?}, was: {:?}",
                test.expected_error_substring, error
            );
        }
    }
}

fn copy_contents(original_test_dir: &Path, test_dir_path: &Path) {
    // copy the contents of original test dir to test_dir
    for entry in walkdir::WalkDir::new(&original_test_dir) {
        let entry = entry.expect("walking original test directory to copy files to /tmp");
        if !entry.file_type().is_file() {
            continue;
        }
        let to_copy = entry.path();
        let destination = test_dir_path.join(to_copy.strip_prefix(&original_test_dir).unwrap());
        std::fs::create_dir_all(destination.parent().unwrap())
            .expect("making parent of file to copy");
        std::fs::copy(to_copy, destination).expect("copying file");
    }
    println!("done copying files");
}
