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)]
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)]
    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)]
    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)]
    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);
        }
    }
}
