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 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 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 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,

    /// 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_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_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(is_v2_component, 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);
        }
    }
}
