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,
    package::make_package,
    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;
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,
    /// Make a Fuchsia package from an unstripped binary
    MakePackage(MakePackage),
    /// 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>,

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

    /// 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 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, ..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)
                    .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 {
                    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::MakePackage(make_package_opts) => {
            println!(
                "make package {}",
                make_package(
                    verbose,
                    &target_options,
                    &make_package_opts.binary_path,
                    &make_package_opts.cmx_path,
                    &make_package_opts.app_name
                )?
            );
            return Ok(());
        }

        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.cmx_path,
                &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 test_args = test_opts.test_args;

            let run_mode = run_switches_to_mode(false, false);
            return run_tests(
                &run_cargo_options
                    .cmx_path(test_opts.cmx_path)
                    .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);
        }
    }
}
