use crate::{
    autotest, build_binary, build_doc,
    build_rustc::build_rustc,
    check_binary,
    cross::run_pkg_config,
    device::{netls, ssh, start_emulator, stop_emulator, StartEmulatorOptions},
    enable_networking, format_project,
    manifest::load_manifest,
    random_story_name, run_binary, run_cargo, run_configure, run_program_on_target,
    run_switches_to_mode, run_tests,
    sdk::TargetOptions,
    write_config, FuchsiaConfig, RunCargoOptions, RunMode, DEFAULT_MOD_NAME,
};
use failure::{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,
    /// 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
    Ssh,
    /// 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)]
    cmx_path: Option<PathBuf>,

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

    /// 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 Use sessionctl to run the binary.
    #[structopt(long)]
    run_with_sessionctl: bool,

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

    /// Name of story to pass to sessionctl.
    #[structopt(short = "n", long)]
    story_name: Option<String>,

    /// Name of mod to pass to sessionctl.
    #[structopt(short, long)]
    mod_name: Option<String>,

    /// Path to sandbox file to use when running.
    #[structopt(long)]
    cmx_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: String,

    /// 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 Use sessionctl to run the binary.
    #[structopt(long)]
    run_with_sessionctl: bool,

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

    /// Name of story to pass to sessionctl.
    #[structopt(short = "n", long)]
    story_name: Option<String>,

    /// Name of mod to pass to sessionctl.
    #[structopt(short, long)]
    mod_name: Option<String>,

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

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

    /// Display all output when running tests.
    #[structopt(long)]
    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>,

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

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

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

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

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

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

    #[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)
                    .manifest_path(opt.manifest_path)
                    .cmx_path(autotest_opts.cmx_path)
                    .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),
                &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,
                    nocapture: false,
                    run_mode: RunMode::Run,
                    story_name: None,
                    mod_name: None,
                    disable_cross: opt.disable_cross_env,
                    manifest_path: None,
                    cmx_path: 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::Fmt => {
            format_project(opt.manifest_path)?;
            return Ok(());
        }

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

        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 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_tiles, run.run_with_sessionctl);
            return run_binary(
                &run_cargo_options
                    .release(run.release)
                    .run_mode(run_mode)
                    .story_name(&to_opt_str(&run.story_name))
                    .mod_name(&to_opt_str(&run.mod_name))
                    .app_name(&Some(&run.app_name))
                    .manifest_path(opt.manifest_path)
                    .cmx_path(run.cmx_path),
                &target_options,
                &params,
            );
        }

        FargoCommand::RunOnTarget(run_on_target) => {
            let run_cargo_options = run_cargo_options.cmx_path(run_on_target.cmx_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_tiles,
                run_on_target.run_with_sessionctl,
            );

            return run_program_on_target(
                &run_on_target.binary_to_run,
                verbose,
                run_on_target.nocapture,
                &fuchsia_config,
                &target_options,
                run_mode,
                &run_cargo_options,
                &run_on_target.story_name.unwrap_or(random_story_name()),
                &run_on_target.mod_name.unwrap_or(DEFAULT_MOD_NAME.to_string()),
                &run_on_target.app_name,
                &run_params,
                None,
            );
        }

        FargoCommand::Ssh => {
            return ssh(opt.verbose, &fuchsia_config, &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 cmx_path = if let Some(cmx_path) = test_opts.cmx_path {
                Some(cmx_path)
            } else {
                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 run_mode = run_switches_to_mode(false, false);
            return run_tests(
                &run_cargo_options
                    .cmx_path(cmx_path)
                    .app_name(&Some(&test_opts.app_name))
                    .run_mode(run_mode)
                    .release(test_opts.release)
                    .manifest_path(opt.manifest_path)
                    .nocapture(test_opts.nocapture),
                false,
                &target_options,
                &params,
                to_opt_str(&test_args),
            );
        }

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