use crate::{
    autotest, build_binary, build_doc,
    build_rustc::build_rustc,
    check_binary,
    cross::run_pkg_config,
    device::{netls, shell, start_emulator, stop_emulator, StartEmulatorOptions},
    enable_networking, format_project,
    linking::extract_linkage_information,
    manifest::load_manifest,
    package::is_v2_sandbox_file,
    run_binary, run_cargo, run_configure, run_program_on_target, run_switches_to_mode, run_tests,
    sdk::TargetOptions,
    write_config, FuchsiaConfig, RunCargoOptions, RunMode,
};
use failure::{bail, Error, ResultExt};
use std::path::PathBuf;
use structopt::StructOpt;

#[derive(Debug, StructOpt)]
enum FargoCommand {
    /// Auto build and test in Fuchsia device or emulator
    Autotest(Autotest),
    /// Build binary targeting Fuchsia device or emulator
    Build(Build),
    /// Build rustc targeting Fuchsia
    BuildRustc(BuildRustc),
    /// Run a cargo command for Fuchsia. Use -- to indicate that all following arguments should be
    /// passed to cargo.
    Cargo(Cargo),
    /// Check binary targeting Fuchsia device or emulator
    Check(Build),
    /// Run a configure script for the cross compilation environment
    Configure(Configure),
    /// Build a package's documentation
    Doc(Doc),
    /// Enable networking for a running emulator
    EnableNetworking,
    /// Extract linkage information
    ExtractLinkage,
    /// Run cargo fmt using the Fuchsia toolchain
    Fmt,
    /// List visible Fuchsia devices
    ListDevices,
    /// Run pkg-config for the cross compilation environment
    PkgConfig(PkgConfig),
    /// Stop all Fuchsia emulators and start a new one
    Restart(Start),
    /// Act as as custom runner for Cargo targeting a Fuchsia device
    RunOnTarget(RunOnTarget),
    /// Run binary on Fuchsia device or emulator
    Run(Run),
    /// Open a shell on Fuchsia device or emulator
    Shell,
    /// Start a Fuchsia emulator
    Start(Start),
    /// Stop all Fuchsia emulators
    Stop,
    /// Run unit tests on Fuchsia device or emulator
    Test(Test),
    /// Write a .cargo/config file to allow cargo to operate correctly for Fuchsia
    WriteConfig,
}

#[derive(Debug, StructOpt)]
struct Autotest {
    /// Build artifacts in release mode, with optimizations.
    #[structopt(long)]
    release: bool,

    /// Path to sandbox file to use when running.
    #[structopt(long, alias = "cmx-path")]
    sandbox_file_path: Option<PathBuf>,

    /// Directory of app as it appears in the manifest file.
    #[structopt(long, default_value = "bin")]
    app_dir: String,

    /// Name of app as it appears in the manifest file.
    #[structopt(long, default_value = "app")]
    app_name: String,

    /// Display all output when running tests.
    #[structopt(long)]
    nocapture: bool,
}

#[derive(Debug, StructOpt)]
struct Build {
    /// Build artifacts in release mode, with optimizations.
    #[structopt(long)]
    release: bool,

    /// Build artifacts in release mode, with optimizations.
    #[structopt(short = "p", long)]
    package: Option<String>,

    /// Name of the bin target to run.
    #[structopt(long)]
    bin: Option<String>,

    /// Build only the specified test target.
    #[structopt(long)]
    test: Option<String>,

    /// Build all the tests.
    #[structopt(long)]
    tests: bool,

    /// Build a specific example from the examples/ dir.
    #[structopt(long)]
    example: Option<String>,

    /// Build all the examples.
    #[structopt(long)]
    examples: bool,
}

#[derive(Debug, StructOpt)]
struct BuildRustc {
    #[structopt(long)]
    rust_root: PathBuf,
}

#[derive(Debug, StructOpt)]
struct Cargo {
    /// Pass options only needed for linking to cargo via RUSTFLAGS.
    #[structopt(long)]
    link: bool,
    subcommand: String,
    cargo_params: Vec<String>,
}

#[derive(Debug, StructOpt)]
struct Configure {
    /// Don't pass --host to configure.
    #[structopt(long)]
    no_host: bool,

    configure_params: Vec<String>,
}

#[derive(Debug, StructOpt)]
struct Doc {
    /// Opens the docs in a browser after the operation
    #[structopt(long)]
    open: bool,

    /// Don't build documentation for dependencies
    #[structopt(long)]
    no_deps: bool,
}

#[derive(Debug, StructOpt)]
#[allow(unused)]
struct MakePackage {
    /// Path to the binary to package
    #[structopt(long)]
    binary_path: PathBuf,

    /// Path to sandbox file to use when running.
    #[structopt(long)]
    cmx_path: Option<PathBuf>,

    /// Directory of app as it appears in the manifest file.
    #[structopt(long, default_value = "bin")]
    app_dir: String,

    /// Name of app as it appears in the manifest file.
    #[structopt(long, default_value = "app")]
    app_name: String,
}

#[derive(Debug, StructOpt)]
struct PkgConfig {
    pkg_config_params: Vec<String>,
}

#[derive(Debug, StructOpt)]
struct Run {
    /// Build artifacts in release mode, with optimizations.
    #[structopt(long)]
    release: bool,

    /// Use run to run the binary.
    #[structopt(long)]
    #[allow(unused)]
    run_with_run: bool,

    /// Use tiles_ctl add to run the binary.
    #[structopt(long)]
    run_with_tiles: bool,

    /// Use tiles_ctl add --flatland to run the binary.
    #[structopt(long)]
    run_with_flatland_tiles: bool,

    /// Use session_control add to run the binary.
    #[structopt(long)]
    run_with_session_control: bool,

    /// Use ffx component run to run the binary.
    #[structopt(long)]
    run_with_ffx_component: bool,

    /// Use ffx test run to run the binary.
    #[structopt(long)]
    run_with_ffx_test: bool,

    /// Use Use sessionctl to run the binary.
    #[structopt(short = "K", long)]
    kill_all: bool,

    /// Directory of app as it appears in the manifest file.
    #[structopt(long, default_value = "bin")]
    app_dir: String,

    /// Name of app as it appears in the manifest file.
    #[structopt(long, default_value = "app")]
    app_name: String,

    /// Path to sandbox file to use when running.
    #[structopt(long, alias = "cmx-path")]
    sandbox_file_path: Option<PathBuf>,

    /// Package to build.
    #[structopt(short, long)]
    package: Option<String>,

    /// Name of the bin target to run.
    #[structopt(long)]
    bin: Option<String>,

    /// Run a specific example from the examples/ dir.
    #[structopt(long)]
    example: Option<String>,
}

#[derive(Debug, StructOpt)]
struct RunOnTarget {
    /// Path to the binary to run.
    binary_to_run: Option<String>,

    /// Use run to run the binary.
    // Allow multiple occurences since fargo writes out a .cargo/config runner
    // command that includes "--run-with-run", but some fargo commands also
    // append their own "--run-with-run" when calling fargo recursively.
    #[structopt(long, multiple = true)]
    #[allow(unused)]
    run_with_run: bool,

    /// Use tiles_ctl add to run the binary.
    #[structopt(long)]
    run_with_tiles: bool,

    /// Use tiles_ctl add --flatland to run the binary.
    #[structopt(long)]
    run_with_flatland_tiles: bool,

    /// Use Use sessionctl to run the binary.
    #[structopt(long)]
    run_with_session_control: bool,

    /// Use ffx component run to run the binary.
    #[structopt(long)]
    run_with_ffx_component: bool,

    /// Use ffx test run to run the binary.
    #[structopt(long)]
    run_with_ffx_test: bool,

    /// Directory of app as it appears in the manifest file.
    #[structopt(long, default_value = "bin")]
    app_dir: String,

    /// Name of app as it appears in the manifest file.
    #[structopt(long, default_value = "app")]
    app_name: String,

    /// Path to sandbox file to use when running.
    #[structopt(long, alias = "cmx-path")]
    sandbox_file_path: Option<PathBuf>,

    /// Additional arguments for the binary.
    runner_args: Vec<String>,

    /// Display all output when running tests.
    // Allow multiple occurences since fargo writes out a .cargo/config runner
    // command that includes "--nocapture", but some tools like VSCode additionally
    // append their own "--nocapture"  when running.
    #[structopt(long, multiple = true)]
    nocapture: bool,
}

#[derive(Debug, StructOpt)]
struct Start {
    /// Start aemu instead of qemu
    #[structopt(short = "a")]
    aemu: bool,

    /// Start a simulator with graphics enabled.
    #[structopt(short = "g")]
    graphics: bool,

    /// Start a simulator with acceleration (for qemu, Linux only)
    #[structopt(short = "k")]
    with_acceleration: bool,

    /// Don't set up networking
    #[structopt(long)]
    no_net: bool,

    /// Do not launch the virtual console service if this option is present
    #[structopt(long)]
    disable_virtcon: bool,
    start_params: Vec<String>,
}

#[derive(Debug, StructOpt)]
struct Test {
    /// Build artifacts in release mode, with optimizations.
    #[structopt(long)]
    release: bool,

    /// Use run to run the test.
    #[structopt(long)]
    #[allow(unused)]
    run_with_run: bool,

    #[structopt(long)]
    /// Test only the specified test target.
    test: Option<String>,

    #[structopt(long)]
    /// Test only this package's library unit tests.
    lib: bool,

    /// Display all output when running tests.
    // Allow multiple occurences since fargo writes out a .cargo/config runner
    // command that includes "--nocapture", but some tools like VSCode additionally
    // append their own "--nocapture"  when running.
    #[structopt(long, multiple = true)]
    nocapture: bool,

    /// Name of the bin target to test.
    #[structopt(long)]
    bin: Option<String>,

    /// Test all binaries.
    #[structopt(long)]
    bins: bool,

    /// RunTest a specific example from the examples/ dir.
    #[structopt(long)]
    example: Option<String>,

    /// Test only this library's documentation.
    #[structopt(long)]
    doc: bool,

    /// Compile, but don't run tests.
    #[structopt(long)]
    no_run: bool,

    /// Arguments to pass to the test runner.
    #[structopt(long)]
    test_args: Option<String>,

    /// Path to sandbox file to use when running.
    #[structopt(long, alias = "cmx-path")]
    sandbox_file_path: Option<PathBuf>,

    /// Directory of app as it appears in the manifest file.
    #[structopt(long, default_value = "bin")]
    app_dir: String,

    /// Name of app as it appears in the manifest file.
    #[structopt(long, default_value = "app")]
    app_name: String,

    /// Package to build.
    #[structopt(short, long)]
    package: Option<String>,

    test_params: Vec<String>,
}

#[derive(Debug, StructOpt)]
#[structopt(name = "fargo", about = "Fargo is a prototype Fuchsia-specific wrapper around Cargo.")]
struct FargoOption {
    /// Print verbose output while performing commands
    #[structopt(short, long)]
    verbose: bool,

    /// Disable the setting of CC, AR and such environmental variables
    #[structopt(long)]
    disable_cross_env: bool,

    /// Name of device to target, needed if there are multiple devices visible on the network
    #[structopt(short = "N", long)]
    device_name: Option<String>,

    /// Path to Cargo.toml
    #[structopt(long, global = true)]
    manifest_path: Option<PathBuf>,

    run_target_first: Option<String>,

    #[structopt(subcommand)]
    command: FargoCommand,
}

fn to_opt_str(value: &Option<String>) -> Option<&str> {
    value.as_ref().map(String::as_str)
}

fn build_params(build_opts: &Build) -> Vec<&str> {
    let mut params = vec![];
    if let Some(package) = build_opts.package.as_ref() {
        params.push("--package");
        params.push(package);
    }
    if let Some(bin) = build_opts.bin.as_ref() {
        params.push("--bin");
        params.push(bin);
    }
    if let Some(test) = build_opts.test.as_ref() {
        params.push("--test");
        params.push(&test);
    }
    if build_opts.tests {
        params.push("--tests");
    }
    if let Some(example) = build_opts.example.as_ref() {
        params.push("--example");
        params.push(example);
    }
    if build_opts.examples {
        params.push("--examples");
    }
    params
}

#[doc(hidden)]
pub fn run() -> Result<(), Error> {
    let opt = FargoOption::from_args();
    let fargo_manifest = load_manifest(&opt.manifest_path)?;
    let verbose = opt.verbose;
    let fuchsia_config = FuchsiaConfig::new_from_fx_exec()?;
    if verbose {
        println!("fuchsia_config = {:#?}", fuchsia_config);
    }

    let target_options =
        TargetOptions::new(&fuchsia_config, opt.device_name.as_ref().map(String::as_str));
    let run_cargo_options = RunCargoOptions {
        verbose,
        fargo_manifest: fargo_manifest.clone(),
        manifest_path: opt.manifest_path.clone(),
        ..RunCargoOptions::default()
    };

    match opt.command {
        FargoCommand::Autotest(autotest_opts) => {
            return autotest(
                &run_cargo_options
                    .release(autotest_opts.release)
                    .linking(true)
                    .manifest_path(opt.manifest_path)
                    .sandbox_file_path(autotest_opts.sandbox_file_path)
                    .app_dir(&Some(&autotest_opts.app_dir))
                    .app_name(&Some(&autotest_opts.app_name))
                    .nocapture(autotest_opts.nocapture),
                &target_options,
            );
        }

        FargoCommand::Build(build_opts) => {
            let params = build_params(&build_opts);
            build_binary(
                &run_cargo_options
                    .release(build_opts.release)
                    .manifest_path(opt.manifest_path)
                    .linking(true),
                &target_options,
                &params,
            )?;
            return Ok(());
        }

        FargoCommand::BuildRustc(build_rustc_opts) => {
            return build_rustc(&build_rustc_opts.rust_root, &target_options);
        }

        FargoCommand::Cargo(cargo_opts) => {
            let cargo_params: Vec<&str> =
                cargo_opts.cargo_params.iter().map(String::as_str).collect();
            return run_cargo(
                &RunCargoOptions {
                    fargo_manifest,
                    verbose,
                    release: false,
                    linking: cargo_opts.link,
                    nocapture: false,
                    run_mode: RunMode::Run,
                    story_name: None,
                    mod_name: None,
                    disable_cross: opt.disable_cross_env,
                    manifest_path: None,
                    sandbox_file_path: None,
                    app_dir: None,
                    app_name: None,
                },
                cargo_opts.subcommand.as_ref(),
                &cargo_params,
                &target_options,
                None,
                None,
            );
        }

        FargoCommand::Check(build_opts) => {
            let params = build_params(&build_opts);
            check_binary(
                &run_cargo_options.release(build_opts.release).manifest_path(opt.manifest_path),
                &target_options,
                &params,
            )?;
            return Ok(());
        }

        FargoCommand::Configure(config_opts) => {
            let configure_params: Vec<&str> =
                config_opts.configure_params.iter().map(String::as_str).collect();
            run_configure(opt.verbose, config_opts.no_host, &configure_params, &target_options)?;
            return Ok(());
        }

        FargoCommand::Doc(doc_opts) => {
            return build_doc(
                &run_cargo_options.manifest_path(opt.manifest_path),
                &target_options,
                doc_opts.no_deps,
                doc_opts.open,
            );
        }

        FargoCommand::EnableNetworking => {
            return enable_networking();
        }

        FargoCommand::ExtractLinkage => {
            return extract_linkage_information();
        }

        FargoCommand::Fmt => {
            format_project(opt.manifest_path)?;
            return Ok(());
        }

        FargoCommand::ListDevices => {
            return netls(opt.verbose);
        }

        FargoCommand::PkgConfig(pkg_config_opts) => {
            let pkg_params: Vec<&str> =
                pkg_config_opts.pkg_config_params.iter().map(String::as_str).collect();
            let exit_code = run_pkg_config(verbose, &pkg_params, &target_options)?;
            if exit_code != 0 {
                ::std::process::exit(exit_code);
            }
            return Ok(());
        }

        FargoCommand::Restart(start_opts) => {
            stop_emulator()?;

            let fx_run_params: Vec<&str> =
                start_opts.start_params.iter().map(String::as_str).collect();

            return start_emulator(
                &StartEmulatorOptions {
                    verbose: verbose,
                    aemu: start_opts.aemu,
                    with_graphics: start_opts.graphics,
                    with_acceleration: start_opts.with_acceleration,
                    with_networking: !start_opts.no_net,
                    disable_virtcon: start_opts.disable_virtcon,
                },
                &fx_run_params,
            );
        }

        FargoCommand::Run(run) => {
            let mut params = vec![];

            if run.kill_all {
                shell(opt.verbose, &target_options, "killall *fargo.cmx").unwrap_or_default();
            }

            if let Some(package) = run.package.as_ref() {
                params.push("--package");
                params.push(package);
            }
            if let Some(bin) = run.bin.as_ref() {
                params.push("--bin");
                params.push(bin);
            }

            if let Some(example) = run.example.as_ref() {
                params.push("--example");
                params.push(example);
            }

            let run_mode = run_switches_to_mode(
                run.run_with_ffx_component,
                run.run_with_ffx_test,
                run.run_with_tiles,
                run.run_with_flatland_tiles,
                run.run_with_session_control,
            );
            return run_binary(
                &run_cargo_options
                    .release(run.release)
                    .run_mode(run_mode)
                    .linking(true)
                    .app_dir(&Some(&run.app_dir))
                    .app_name(&Some(&run.app_name))
                    .manifest_path(opt.manifest_path)
                    .sandbox_file_path(run.sandbox_file_path),
                &target_options,
                &params,
            );
        }

        FargoCommand::RunOnTarget(run_on_target) => {
            let run_cargo_options =
                run_cargo_options.sandbox_file_path(run_on_target.sandbox_file_path);
            let run_params: Vec<&str> = run_on_target.runner_args.iter().map(|s| &**s).collect();
            let run_mode = run_switches_to_mode(
                run_on_target.run_with_ffx_component,
                run_on_target.run_with_ffx_test,
                run_on_target.run_with_tiles,
                run_on_target.run_with_flatland_tiles,
                run_on_target.run_with_session_control,
            );

            let binary_to_run = if let Some(binary_to_run) = run_on_target.binary_to_run {
                binary_to_run
            } else {
                if let Some(binary_to_run) = opt.run_target_first {
                    binary_to_run
                } else {
                    bail!("The fargo test runner was not passed a binary to run")
                }
            };

            return run_program_on_target(
                &binary_to_run,
                verbose,
                run_on_target.nocapture,
                &target_options,
                run_mode,
                &run_cargo_options,
                &run_on_target.app_dir,
                &run_on_target.app_name,
                &run_params,
                None,
            );
        }

        FargoCommand::Shell => {
            return shell(opt.verbose, &target_options, "");
        }

        FargoCommand::Start(start_opts) => {
            let fx_run_params: Vec<&str> =
                start_opts.start_params.iter().map(String::as_str).collect();

            return start_emulator(
                &StartEmulatorOptions {
                    verbose: verbose,
                    aemu: start_opts.aemu,
                    with_graphics: start_opts.graphics,
                    with_acceleration: start_opts.with_acceleration,
                    with_networking: !start_opts.no_net,
                    disable_virtcon: start_opts.disable_virtcon,
                },
                &fx_run_params,
            );
        }

        FargoCommand::Stop => {
            return stop_emulator();
        }

        FargoCommand::Test(test_opts) => {
            let mut params = vec![];
            if let Some(package) = test_opts.package.as_ref() {
                params.push("--package");
                params.push(package);
            }

            if let Some(bin) = test_opts.bin.as_ref() {
                params.push("--bin");
                params.push(bin);
            }

            if let Some(example) = test_opts.example.as_ref() {
                params.push("--example");
                params.push(example);
            }

            let test_params: Vec<&str> = test_opts.test_params.iter().map(String::as_str).collect();

            params.extend(test_params);

            if let Some(test) = test_opts.test.as_ref() {
                params.push("--test");
                params.push(test);
            }

            let sandbox_file_path = match test_opts.sandbox_file_path {
                Some(sandbox_file_path) => Some(sandbox_file_path),
                None => {
                    let cwd: PathBuf = if let Some(actual_manifest_path) =
                        opt.manifest_path.as_ref()
                    {
                        actual_manifest_path.parent().expect("manifest_path parent").to_path_buf()
                    } else {
                        std::fs::canonicalize(std::env::current_dir()?)
                            .context("autotest: canonicalize working directory")?
                    };
                    let test_cmx_file = cwd.join("meta").join("test.cmx");
                    if test_cmx_file.exists() {
                        Some(test_cmx_file)
                    } else {
                        None
                    }
                }
            };

            let test_args = test_opts.test_args;

            let is_v2_component = if let Some(ref sandbox_file_path) = sandbox_file_path {
                is_v2_sandbox_file(sandbox_file_path)?
            } else {
                // If no sandbox file is provided, default to running as a v1 component (.cmx),
                // because the autogenerated sandbox file in package.rs is currently a v1 (.cmx)
                // file.
                false
            };
            let run_mode = run_switches_to_mode(false, is_v2_component, false, false, false);

            return run_tests(
                &run_cargo_options
                    .sandbox_file_path(sandbox_file_path)
                    .app_dir(&Some(&test_opts.app_dir))
                    .app_name(&Some(&test_opts.app_name))
                    .run_mode(run_mode)
                    .release(test_opts.release)
                    .linking(true)
                    .manifest_path(opt.manifest_path)
                    .nocapture(test_opts.nocapture),
                test_opts.no_run,
                test_opts.doc,
                test_opts.lib,
                test_opts.bins,
                &target_options,
                &params,
                to_opt_str(&test_args),
            );
        }

        FargoCommand::WriteConfig => {
            return write_config(&run_cargo_options, &target_options);
        }
    }
}
