// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate core;

use clap::Parser as _;
use cmd_runner::{license_checker::LicenseSubcommand, run_cmd, run_cmd_shell, YellowStderr};
use env_logger::Env;
use license::LICENSE_CHECKER;
use std::{env, ffi::OsString, path};

mod crypto_ffi;
mod ffi;
mod fuzzers;
mod jni;
mod license;
mod ukey2;

fn main() -> anyhow::Result<()> {
    env_logger::Builder::from_env(Env::default().default_filter_or("info")).init();
    let cli: Cli = Cli::parse();

    let root_dir = path::PathBuf::from(
        env::var("CARGO_MANIFEST_DIR").expect("Must be run via Cargo to establish root directory"),
    );

    match cli.subcommand {
        Subcommand::RunDefaultChecks(ref check_options) => {
            run_default_checks(&root_dir, check_options)?;
            print!(concat!(
                "Congratulations, the default checks passed. Since you like quality, here are\n",
                "some more checks you may like:\n",
                "    cargo run -- run-rust-fuzzers\n",
                "    cargo run -- check-stack-usage\n",
            ));
        }
        Subcommand::VerifyCi { ref check_options } => verify_ci(&root_dir, check_options)?,
        Subcommand::CleanEverything => clean_everything(&root_dir)?,
        Subcommand::CheckFormat(ref options) => check_format(&root_dir, options)?,
        Subcommand::CheckWorkspace(ref options) => check_workspace(&root_dir, options)?,
        Subcommand::CheckAllFfi(ref options) => ffi::check_ffi(&root_dir, options)?,
        Subcommand::BuildBoringssl => crypto_ffi::build_boringssl(&root_dir)?,
        Subcommand::CheckBoringssl(ref options) => crypto_ffi::check_boringssl(&root_dir, options)?,
        Subcommand::CheckBoringsslAtLatest(ref options) => {
            crypto_ffi::check_boringssl_at_head(&root_dir, options)?
        }
        Subcommand::RunRustFuzzers => fuzzers::run_rust_fuzzers(&root_dir)?,
        Subcommand::CheckFuzztest => fuzzers::build_fuzztest_unit_tests(&root_dir)?,
        Subcommand::License(license_subcommand) => {
            license_subcommand.run(&LICENSE_CHECKER, &root_dir)?
        }
        Subcommand::CheckUkey2Ffi(ref options) => ukey2::check_ukey2_ffi(&root_dir, options)?,
        Subcommand::RunUkey2JniTests => jni::run_ukey2_jni_tests(&root_dir)?,
        Subcommand::RunNpJavaFfiTests => jni::run_np_java_ffi_tests(&root_dir)?,
        Subcommand::CheckLdtJni => jni::check_ldt_jni(&root_dir)?,
        Subcommand::CheckLdtCmake(ref options) => ffi::check_ldt_cmake(&root_dir, options)?,
        Subcommand::CheckNpFfiCmake(ref options) => ffi::check_np_ffi_cmake(&root_dir, options)?,
        Subcommand::RunKotlinTests => jni::run_kotlin_tests(&root_dir)?,
    }

    Ok(())
}

fn check_format(root: &path::Path, options: &FormatterOptions) -> anyhow::Result<()> {
    // Rust format
    {
        let fmt_command = if options.reformat { "cargo fmt" } else { "cargo fmt --check" };
        run_cmd_shell(root, fmt_command)?;
    }

    // Java format. This uses the jar downloaded as part of the CI script or the local
    // `google-java-format` executable. The jar file path can be overridden with the
    // `GOOGLE_JAVA_FORMAT_ALL_DEPS_JAR` environment variable. See
    // <go/google-java-format#installation> for setup instructions for your dev environment if
    // needed.
    {
        let jar_path = std::env::var("GOOGLE_JAVA_FORMAT_ALL_DEPS_JAR").unwrap_or_else(|_| {
            "/opt/google-java-format/google-java-format-all-deps.jar".to_owned()
        });

        let mut fmt_command: Vec<OsString> = Vec::new();

        if path::PathBuf::from(&jar_path).exists() {
            fmt_command.extend(["java".into(), "-jar".into(), jar_path.into()]);
        } else {
            fmt_command.push("google-java-format".into());
        }

        if options.reformat {
            fmt_command.push("-i".into());
        } else {
            fmt_command.extend(["--set-exit-if-changed".into(), "--dry-run".into()]);
        }

        let root_str =
            glob::Pattern::escape(root.to_str().expect("Non-unicode paths are not supported"));
        let search = format!("{}/**/*.java", root_str);
        let java_files: Vec<_> = glob::glob(&search).unwrap().filter_map(Result::ok).collect();

        for file_set in java_files.chunks(100) {
            let mut args = fmt_command[1..].to_vec();
            args.extend(file_set.iter().map(OsString::from));

            run_cmd::<YellowStderr, _, _, _>(root, &fmt_command[0], args)?;
        }
    }

    Ok(())
}

pub fn check_workspace(root: &path::Path, options: &CheckOptions) -> anyhow::Result<()> {
    log::info!("Running cargo checks on workspace");

    // ensure formatting is correct (Check for it first because it is fast compared to running tests)
    check_format(root, &options.formatter_options)?;

    for cargo_cmd in [
        // make sure everything compiles
        "cargo check --workspace --all-targets --quiet",
        // run all the tests
        &options.cargo_options.test("check_workspace", "--workspace --quiet"),
        // Test ukey2 builds with different crypto providers
        &options.cargo_options.test(
            "check_workspace_ukey2",
            "-p ukey2_connections -p ukey2_rs --no-default-features --features test_rustcrypto",
        ),
        // ensure the docs are valid (cross-references to other code, etc)
        concat!(
            "RUSTDOCFLAGS='--deny warnings' ",
            "cargo doc --quiet --workspace --no-deps --document-private-items ",
            "--target-dir target/dist_docs",
        ),
        "cargo clippy --all-targets --workspace -- --deny warnings",
        "cargo deny --workspace check",
    ] {
        run_cmd_shell(root, cargo_cmd)?;
    }

    Ok(())
}

/// Runs default checks that are suiable for verifying a local change.
pub fn run_default_checks(root: &path::Path, check_options: &CheckOptions) -> anyhow::Result<()> {
    license::LICENSE_CHECKER.check(root)?;
    check_workspace(root, check_options)?;
    crypto_ffi::check_boringssl(root, &check_options.cargo_options)?;
    ffi::check_ffi(root, &check_options.cargo_options)?;
    if !cfg!(target_os = "windows") {
        fuzzers::build_fuzztest_unit_tests(root)?;
    }
    crypto_ffi::check_boringssl_at_head(root, &check_options.cargo_options)?;
    ukey2::check_ukey2_ffi(root, &check_options.cargo_options)?;
    if !cfg!(target_os = "windows") {
        // Test below requires Java SE 9, but on Windows we only have Java SE 8 installed
        jni::run_np_java_ffi_tests(root)?;
    }
    jni::run_ukey2_jni_tests(root)?;
    Ok(())
}

/// Runs checks to ensure lints are passing and all targets are building
pub fn verify_ci(root: &path::Path, check_options: &CheckOptions) -> anyhow::Result<()> {
    run_default_checks(root, check_options)?;
    Ok(())
}

pub fn clean_everything(root: &path::Path) -> anyhow::Result<()> {
    run_cmd_shell(root, "cargo clean")?;
    run_cmd_shell(&root.join("presence/np_c_ffi"), "cargo clean")?;
    run_cmd_shell(&root.join("crypto/crypto_provider_boringssl"), "cargo clean")?;
    run_cmd_shell(&root.join("connections/ukey2/ukey2_c_ffi"), "cargo clean")?;
    run_cmd_shell(&root.join("presence/np_java_ffi"), "./gradlew :clean")?;
    Ok(())
}

#[derive(clap::Parser)]
struct Cli {
    #[clap(subcommand)]
    subcommand: Subcommand,
}

#[derive(clap::Subcommand, Debug, Clone)]
enum Subcommand {
    /// Runs all of the checks that CI runs
    VerifyCi {
        #[command(flatten)]
        check_options: CheckOptions,
    },
    /// Runs the default set of checks suitable for verifying local changes.
    RunDefaultChecks(CheckOptions),
    /// Cleans the main workspace and all sub projects - useful if upgrading rust compiler version
    /// and need dependencies to be compiled with the same version
    CleanEverything,
    /// Checks code formatting
    CheckFormat(FormatterOptions),
    /// Checks everything included in the top level workspace
    CheckWorkspace(CheckOptions),
    /// Clones boringssl and uses bindgen to generate the rust crate
    BuildBoringssl,
    /// Run crypto provider tests using boringssl backend
    CheckBoringssl(CargoOptions),
    /// Checks out latest boringssl commit and runs our tests against it
    CheckBoringsslAtLatest(CargoOptions),
    /// Build and run pure Rust fuzzers for 10000 runs
    RunRustFuzzers,
    /// Builds and runs fuzztest property based unit tests
    CheckFuzztest,
    /// Builds and runs tests for all C/C++ projects. This is a combination of CheckNpFfi,
    /// CheckLdtFfi, and CheckCmakeBuildAndTests
    CheckAllFfi(CargoOptions),
    /// Checks the CMake build and runs all of the C/C++ tests
    CheckLdtCmake(CargoOptions),
    /// Checks the CMake build and runs all of the C/C++ tests
    CheckNpFfiCmake(CargoOptions),
    #[command(flatten)]
    License(LicenseSubcommand),
    /// Builds and runs tests for the UKEY2 FFI
    CheckUkey2Ffi(CargoOptions),
    /// Checks the build of ldt_jni wrapper with non default features, ie boringssl
    CheckLdtJni,
    /// Runs the kotlin tests of the LDT Jni API
    RunKotlinTests,
    /// Checks the build of the ukey2_jni wrapper and runs tests
    RunUkey2JniTests,
    /// Checks the build of the np_java_ffi wrapper and runs tests
    RunNpJavaFfiTests,
}

#[derive(clap::Args, Debug, Clone, Default)]
pub struct FormatterOptions {
    #[arg(long, help = "reformat files files in the workspace with the code formatter")]
    reformat: bool,
}

#[derive(clap::Args, Debug, Clone, Default)]
pub struct CheckOptions {
    #[command(flatten)]
    formatter_options: FormatterOptions,
    #[command(flatten)]
    cargo_options: CargoOptions,
}

#[derive(clap::Args, Debug, Clone, Default)]
pub struct CargoOptions {
    #[arg(long, help = "whether to run cargo with --locked")]
    locked: bool,
    #[arg(long, help = "gather coverage metrics")]
    coverage: bool,
}

impl CargoOptions {
    /// Run `cargo test` or `cargo llvm-cov` depending on the configured options.
    pub fn test(&self, tag: &str, args: impl AsRef<str>) -> String {
        format!(
            "cargo {subcommand} {locked} {args} {cov_args} -- --color=always",
            subcommand = if self.coverage { "llvm-cov" } else { "test" },
            locked = if self.locked { "--locked" } else { "" },
            args = args.as_ref(),
            cov_args = if self.coverage {
                format!("--lcov --output-path \"target/{tag}.info\"")
            } else {
                String::default()
            },
        )
    }
}
