// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//! While fargo is mainly intended to be a command line tool, this library
//! exposes one function, `run_cargo`, that could be integrated directly into
//! Rust programs that want to cross compile cargo crates on Fuchsia.

#![recursion_limit = "1024"]

mod build_rustc;
mod cross;
mod device;
mod sdk;
mod utils;

pub use crate::sdk::{FuchsiaConfig, TargetOptions};

use crate::build_rustc::build_rustc;
use crate::cross::{pkg_config_path, run_configure, run_pkg_config};
use crate::device::{
    enable_networking, netaddr, netls, scp_to_device, ssh, start_emulator, stop_emulator,
    StartEmulatorOptions,
};
use crate::sdk::{
    cargo_out_dir, cargo_path, clang_archiver_path, clang_c_compiler_path, clang_cpp_compiler_path,
    clang_ranlib_path, clang_resource_dir, rustc_path, rustdoc_path, shared_libraries_path,
    sysroot_path, zircon_build_path,
};
use crate::utils::strip_binary;

use clap::{App, AppSettings, Arg, SubCommand};
use failure::{bail, err_msg, format_err, Error, ResultExt};
use std::fs;
use std::fs::File;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::process::Command;
use std::time::SystemTime;

fn copy_to_target(
    source_path: &PathBuf,
    verbose: bool,
    config: &FuchsiaConfig,
    target_options: &TargetOptions<'_, '_>,
) -> Result<String, Error> {
    let netaddr = netaddr(verbose, target_options)?;
    if verbose {
        println!("netaddr {}", netaddr);
    }
    let destination_path = format!(
        "/tmp/{}",
        source_path
            .file_name()
            .ok_or(format_err!("file_name failed on {:#?}", source_path))?
            .to_string_lossy()
    );
    println!("copying {} to {}", source_path.to_string_lossy(), destination_path);
    scp_to_device(verbose, config, &netaddr, &source_path, &destination_path)?;
    Ok(destination_path)
}

fn run_program_on_target(
    filename: &str,
    verbose: bool,
    nocapture: bool,
    config: &FuchsiaConfig,
    target_options: &TargetOptions<'_, '_>,
    run_mode: RunMode,
    story_name: &str,
    mod_name: &str,
    params: &[&str],
    test_args: Option<&str>,
) -> Result<(), Error> {
    let source_path = PathBuf::from(&filename);
    let stripped_source_path = strip_binary(&source_path)?;
    let destination_path = copy_to_target(&stripped_source_path, verbose, config, target_options)?;
    let mut command_string = match run_mode {
        RunMode::Tiles => "tiles_ctl add ".to_string(),
        RunMode::Ermine => {
            format!("sessionctl --story_name={} --mod_name={} --mod_url=", story_name, mod_name)
        }
        RunMode::Run => "run ".to_string(),
        RunMode::Normal => "".to_string(),
    };
    command_string.push_str(&destination_path);

    match run_mode {
        RunMode::Ermine => {
            command_string.push_str(" add_mod");
        }
        _ => (),
    }

    if nocapture {
        command_string.push_str(" --");
        command_string.push_str(NOCAPTURE);
    }

    for param in params {
        command_string.push(' ');
        command_string.push_str(param);
    }

    if let Some(test_args_str) = test_args {
        command_string.push_str(" -- ");
        command_string.push_str(test_args_str);
    }

    if verbose {
        println!("running {}", command_string);
    }

    ssh(verbose, config, target_options, &command_string)?;
    Ok(())
}

extern crate notify;

use notify::{RecommendedWatcher, RecursiveMode, Watcher};
use std::sync::mpsc::channel;
use std::time::Duration;

fn autotest(
    run_cargo_options: &RunCargoOptions,
    target_options: &TargetOptions<'_, '_>,
) -> Result<(), Error> {
    let (tx, rx) = channel();
    let mut watcher: RecommendedWatcher =
        Watcher::new(tx, Duration::from_secs(1)).context("autotest: watcher creation failed")?;

    let cwd = std::fs::canonicalize(std::env::current_dir()?)
        .context("autotest: canonicalize working directory")?;
    let tgt = cwd.join("target");
    let git = cwd.join(".git");

    watcher.watch(&cwd, RecursiveMode::Recursive).context("autotest: watch failed")?;

    println!("autotest: started");
    loop {
        let event = rx.recv().context("autotest: watch recv failed")?;
        match event {
            notify::DebouncedEvent::Create(path)
            | notify::DebouncedEvent::Write(path)
            | notify::DebouncedEvent::Chmod(path)
            | notify::DebouncedEvent::Remove(path)
            | notify::DebouncedEvent::Rename(path, _) => {
                // TODO(raggi): provide a fuller ignore flag/pattern match solution here.
                if !path.starts_with(&tgt) && !path.starts_with(&git) {
                    println!("autotest: running tests because {:?}", path);
                    run_tests(run_cargo_options, false, target_options, &[], None).ok();
                }
            }
            _ => {}
        }
    }
}

fn run_tests(
    run_cargo_options: &RunCargoOptions,
    no_run: bool,
    target_options: &TargetOptions<'_, '_>,
    params: &[&str],
    target_params: Option<&str>,
) -> Result<(), Error> {
    let mut args = vec![];

    if no_run {
        args.push("--no-run");
    }

    for param in params {
        args.push(param);
    }

    if let Some(target_params) = target_params {
        let formatted_target_params = format!("--args={}", target_params);
        run_cargo(
            &run_cargo_options,
            "test",
            &args,
            target_options,
            None,
            Some(&formatted_target_params),
        )?;
    } else {
        run_cargo(&run_cargo_options, "test", &args, target_options, None, None)?;
    }

    Ok(())
}

fn build_binary(
    run_cargo_options: &RunCargoOptions,
    target_options: &TargetOptions<'_, '_>,
    params: &[&str],
) -> Result<(), Error> {
    run_cargo(run_cargo_options, "build", params, target_options, None, None)
}

fn check_binary(
    run_cargo_options: &RunCargoOptions,
    target_options: &TargetOptions<'_, '_>,
    params: &[&str],
) -> Result<(), Error> {
    run_cargo(run_cargo_options, "check", params, target_options, None, None)
}

fn run_binary(
    run_cargo_options: &RunCargoOptions,
    target_options: &TargetOptions<'_, '_>,
    params: &[&str],
) -> Result<(), Error> {
    run_cargo(run_cargo_options, RUN, params, target_options, None, None)?;
    Ok(())
}

fn build_doc(
    run_cargo_options: &RunCargoOptions,
    target_options: &TargetOptions<'_, '_>,
    no_deps: bool,
    open: bool,
) -> Result<(), Error> {
    let mut args = vec![];
    if no_deps {
        args.push("--no-deps");
    }
    if open {
        args.push("--open");
    }
    run_cargo(run_cargo_options, DOC, &args, &target_options, None, None)
}

fn load_driver(
    run_cargo_options: &RunCargoOptions,
    config: &FuchsiaConfig,
    target_options: &TargetOptions<'_, '_>,
) -> Result<(), Error> {
    let args = vec![];
    run_cargo(run_cargo_options, "build", &args, target_options, None, None)?;
    let cwd = std::env::current_dir()?;
    let package = cwd
        .file_name()
        .ok_or(err_msg("No current directory"))?
        .to_str()
        .ok_or(err_msg("Invalid current directory"))?;
    let filename = cargo_out_dir(target_options)?.join(format!("lib{}.so", package));
    let destination_path =
        copy_to_target(&filename, run_cargo_options.verbose, config, target_options)?;
    let command_string = format!("dm add-driver:{}", destination_path);
    if run_cargo_options.verbose {
        println!("running {}", command_string);
    }
    ssh(run_cargo_options.verbose, config, target_options, &command_string)?;
    Ok(())
}

#[derive(Clone, Copy, Debug)]
pub enum RunMode {
    Normal,
    Run,
    Tiles,
    Ermine,
}

fn run_switches_to_mode(tiles: bool, run: bool, ermine: bool) -> RunMode {
    if tiles {
        RunMode::Tiles
    } else if run {
        RunMode::Run
    } else if ermine {
        RunMode::Ermine
    } else {
        RunMode::Normal
    }
}

fn random_story_name() -> String {
    let secs = match SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) {
        Ok(n) => n.as_secs(),
        Err(_) => panic!("SystemTime before UNIX EPOCH!"),
    };
    format!("fargo-story-{}", secs)
}

#[derive(Debug)]
pub struct RunCargoOptions {
    pub verbose: bool,
    pub release: bool,
    pub run_mode: RunMode,
    pub story_name: Option<String>,
    pub mod_name: Option<String>,
    pub disable_cross: bool,
    pub nocapture: bool,
    pub manifest_path: Option<PathBuf>,
}

impl RunCargoOptions {
    pub fn new(verbose: bool, release: bool) -> RunCargoOptions {
        RunCargoOptions {
            verbose,
            release,
            nocapture: false,
            run_mode: RunMode::Normal,
            story_name: None,
            mod_name: None,
            disable_cross: false,
            manifest_path: None,
        }
    }

    pub fn disable_cross(&self, disable_cross: bool) -> RunCargoOptions {
        RunCargoOptions {
            verbose: self.verbose,
            release: self.release,
            nocapture: self.nocapture,
            run_mode: self.run_mode,
            story_name: self.story_name.clone(),
            mod_name: self.mod_name.clone(),
            disable_cross,
            manifest_path: self.manifest_path.clone(),
        }
    }

    pub fn release(&self, release: bool) -> RunCargoOptions {
        RunCargoOptions {
            verbose: self.verbose,
            release: release,
            nocapture: self.nocapture,
            run_mode: self.run_mode,
            story_name: self.story_name.clone(),
            mod_name: self.mod_name.clone(),
            disable_cross: self.disable_cross,
            manifest_path: self.manifest_path.clone(),
        }
    }

    pub fn nocapture(&self, nocapture: bool) -> RunCargoOptions {
        RunCargoOptions {
            verbose: self.verbose,
            release: self.release,
            nocapture: nocapture,
            run_mode: self.run_mode,
            story_name: self.story_name.clone(),
            mod_name: self.mod_name.clone(),
            disable_cross: self.disable_cross,
            manifest_path: self.manifest_path.clone(),
        }
    }

    pub fn run_mode(&self, run_mode: RunMode) -> RunCargoOptions {
        RunCargoOptions {
            verbose: self.verbose,
            release: self.release,
            nocapture: self.nocapture,
            run_mode: run_mode,
            story_name: self.story_name.clone(),
            mod_name: self.mod_name.clone(),
            disable_cross: self.disable_cross,
            manifest_path: self.manifest_path.clone(),
        }
    }

    pub fn story_name(&self, story_name: &Option<&str>) -> RunCargoOptions {
        RunCargoOptions {
            verbose: self.verbose,
            release: self.release,
            nocapture: self.nocapture,
            run_mode: self.run_mode,
            story_name: story_name.map(|name| name.to_string()),
            mod_name: self.mod_name.clone(),
            disable_cross: self.disable_cross,
            manifest_path: self.manifest_path.clone(),
        }
    }

    pub fn mod_name(&self, mod_name: &Option<&str>) -> RunCargoOptions {
        RunCargoOptions {
            verbose: self.verbose,
            release: self.release,
            nocapture: self.nocapture,
            run_mode: self.run_mode,
            story_name: self.story_name.clone(),
            mod_name: mod_name.map(|name| name.to_string()),
            disable_cross: self.disable_cross,
            manifest_path: self.manifest_path.clone(),
        }
    }

    pub fn manifest_path(&self, manifest_path: Option<PathBuf>) -> RunCargoOptions {
        RunCargoOptions {
            verbose: self.verbose,
            release: self.release,
            nocapture: self.nocapture,
            run_mode: self.run_mode,
            story_name: self.story_name.clone(),
            mod_name: self.mod_name.clone(),
            disable_cross: self.disable_cross,
            manifest_path: manifest_path,
        }
    }

    pub fn get_story_name(&self) -> String {
        if let Some(ref name) = self.story_name {
            name.clone()
        } else {
            random_story_name()
        }
    }

    pub fn get_mod_name(&self) -> String {
        if let Some(ref name) = self.mod_name {
            name.clone()
        } else {
            DEFAULT_MOD_NAME.to_string()
        }
    }
}

fn get_triple_cpu(target_options: &TargetOptions<'_, '_>) -> String {
    if (target_options.config.fuchsia_arch) == X64 { "x86_64" } else { "aarch64" }.to_string()
}

fn get_target_triple(target_options: &TargetOptions<'_, '_>) -> String {
    let triple_cpu = get_triple_cpu(target_options);

    format!("{}-fuchsia", triple_cpu)
}

fn get_rustflags(
    target_options: &TargetOptions<'_, '_>,
    sysroot_as_path: &PathBuf,
) -> Result<String, Error> {
    let target_triple = get_target_triple(target_options);
    let sysroot_lib_pathbuf = sysroot_as_path.join("lib");
    let sysroot_lib = sysroot_lib_pathbuf.to_string_lossy();
    let clang_resource_lib = clang_resource_dir(&target_triple)?.join(&target_triple).join("lib");

    let mut rust_flags = vec![
        "-L".to_string(),
        sysroot_lib.to_string(),
        "-Clink-arg=--pack-dyn-relocs=relr".to_string(),
        "-Clink-arg=--threads".to_string(),
        format!("-Clink-arg=-L{}", sysroot_lib),
        format!("-Clink-arg=-L{}", clang_resource_lib.to_string_lossy()),
        format!("-Clink-arg=--sysroot={}", sysroot_as_path.to_string_lossy()),
        format!("-Lnative={}", shared_libraries_path(target_options)?.to_string_lossy()),
    ];

    if get_triple_cpu(target_options) == "aarch64" {
        rust_flags.push("-Clink-arg=--fix-cortex-a53-843419".to_string());
    }

    Ok(rust_flags.join(" "))
}

fn make_fargo_command(
    runner: Option<PathBuf>,
    options: &RunCargoOptions,
    nocapture: bool,
    target_options: &TargetOptions<'_, '_>,
    additional_target_args: Option<&str>,
) -> Result<String, Error> {
    let tiles_arg = format!("--{}", RUN_WITH_TILES);
    let ermine_arg = format!(
        "--{} --story-name={} --mod-name={}",
        RUN_WITH_SESSIONCTL,
        options.get_story_name(),
        options.get_mod_name()
    );
    let run_arg = format!("--{}", RUN_WITH_RUN);
    let nocapture_arg = format!("--{}", NOCAPTURE);

    let fargo_path = if let Some(runner) = runner {
        runner
    } else {
        fs::canonicalize(std::env::current_exe()?)?
    };

    let mut runner_args = vec![
        fargo_path.to_str().ok_or_else(|| err_msg("unable to convert path to utf8 encoding"))?,
    ];

    if options.verbose {
        runner_args.push("-v");
    }

    if let Some(device_name) = target_options.device_name {
        runner_args.push("--device-name");
        runner_args.push(device_name);
    }

    runner_args.push(RUN_ON_TARGET);

    if nocapture {
        runner_args.push(&nocapture_arg);
    }

    match options.run_mode {
        RunMode::Normal => (),
        RunMode::Tiles => runner_args.push(&tiles_arg),
        RunMode::Ermine => runner_args.push(&ermine_arg),
        RunMode::Run => runner_args.push(&run_arg),
    }

    if let Some(args_for_target) = additional_target_args {
        runner_args.push(&args_for_target);
    }

    Ok(runner_args.join(" "))
}

fn convert_manifest_path(possible_path: &Option<&str>) -> Option<PathBuf> {
    if let Some(path) = possible_path {
        Some(PathBuf::from(path))
    } else {
        None
    }
}

/// Runs the cargo tool configured to target Fuchsia. When used as a library,
/// the runner options must contain the path to fargo or some other program
/// that implements the `run-on-target` subcommand in a way compatible with
/// fargo.
///
/// # Examples
///
/// ```
/// use fargo::{run_cargo, FuchsiaConfig, RunCargoOptions, RunMode, TargetOptions};
///
/// let config = FuchsiaConfig::default();
/// let target_options = TargetOptions::new(&config, None);
/// run_cargo(
///     &RunCargoOptions {
///         verbose: false,
///         release: true,
///         nocapture: false,
///         run_mode: RunMode::Normal,
///         story_name: None,
///         mod_name: None,
///         disable_cross: false,
///         manifest_path: None,
///     },
///     "help",
///     &[],
///     &target_options,
///     None,
///     None,
/// );
/// ```
pub fn run_cargo(
    options: &RunCargoOptions,
    subcommand: &str,
    args: &[&str],
    target_options: &TargetOptions<'_, '_>,
    runner: Option<PathBuf>,
    additional_target_args: Option<&str>,
) -> Result<(), Error> {
    if options.verbose {
        println!("target_options = {:?}", target_options);
    }

    let triple_cpu = get_triple_cpu(target_options);
    let target_triple = get_target_triple(target_options);
    let mut target_args = vec!["--target", &target_triple];

    if options.release {
        target_args.push("--release");
    }

    if options.verbose {
        println!("target_options.target_cpu = {:?}", target_options.config.fuchsia_arch);
        println!("triple_cpu = {:?}", triple_cpu);
        println!("target_triple = {:?}", target_triple);
        println!("target_args = {:?}", target_args);
        println!("options = {:?}", options);
    }

    let target_triple_uc = format!("{}_fuchsia", triple_cpu).to_uppercase();

    let fargo_command = make_fargo_command(
        runner,
        &options,
        options.nocapture,
        target_options,
        additional_target_args,
    )?;

    if options.verbose {
        println!("fargo_command: {:?}", fargo_command);
    }

    let pkg_path = pkg_config_path(target_options)?;
    let mut cmd = Command::new(cargo_path()?);
    let sysroot_as_path = sysroot_path(target_options)?;
    let sysroot_as_str = sysroot_as_path.to_string_lossy();

    let args: Vec<&str> = args.iter().map(|a| if *a == "++" { "--" } else { *a }).collect();

    let runner_env_name = format!("CARGO_TARGET_{}_RUNNER", target_triple_uc);
    let rustflags_env_name = format!("CARGO_TARGET_{}_RUSTFLAGS", target_triple_uc);

    if options.verbose {
        println!("runner_env_name: {:?}", runner_env_name);
        println!("rustflags_env_name: {:?}", rustflags_env_name);
        println!("rustc_path: {:?}", rustc_path()?.to_string_lossy());
        println!("cargo_path: {:?}", cargo_path()?.to_string_lossy());
    }

    cmd.env(runner_env_name, fargo_command)
        .env(rustflags_env_name, get_rustflags(target_options, &sysroot_as_path)?)
        .env("RUSTC", rustc_path()?.to_string_lossy().as_ref())
        .env("RUSTDOC", rustdoc_path()?.to_string_lossy().as_ref())
        .env("RUSTDOCFLAGS", "--cap-lints allow -Z unstable-options")
        .env("FUCHSIA_SHARED_ROOT", shared_libraries_path(target_options)?)
        .env("ZIRCON_BUILD_ROOT", zircon_build_path(target_options)?)
        .arg(subcommand)
        .args(target_args)
        .args(args);

    if let Some(ref manifest_path) = options.manifest_path {
        let manifest_args: Vec<&str> = vec![
            "--manifest-path",
            manifest_path.to_str().expect("path to string failed for manifest_path"),
        ];
        cmd.args(manifest_args);
    }

    if !options.disable_cross {
        let cc_env_name = format!("CC_{}", target_triple_uc);
        let cxx_env_name = format!("CXX_{}", target_triple_uc);
        let cflags_env_name = format!("CFLAGS_{}", target_triple_uc);
        let ar_env_name = format!("AR_{}", target_triple_uc);
        cmd.env(cc_env_name, clang_c_compiler_path()?.to_string_lossy().as_ref())
            .env(cxx_env_name, clang_cpp_compiler_path()?.to_string_lossy().as_ref())
            .env(cflags_env_name, format!("--sysroot={}", sysroot_as_str))
            .env(ar_env_name, clang_archiver_path()?.to_string_lossy().as_ref())
            .env("RANLIB", clang_ranlib_path()?.to_string_lossy().as_ref())
            .env("PKG_CONFIG_ALL_STATIC", "1")
            .env("PKG_CONFIG_ALLOW_CROSS", "1")
            .env("PKG_CONFIG_PATH", "")
            .env("PKG_CONFIG_LIBDIR", pkg_path);
    }

    if options.verbose {
        println!("cargo cmd: {:?}", cmd);
    }

    let cargo_status = cmd.status()?;
    if !cargo_status.success() {
        bail!("cargo exited with status {:?}", cargo_status,);
    }

    Ok(())
}

fn write_config(
    options: &RunCargoOptions,
    target_options: &TargetOptions<'_, '_>,
) -> Result<(), Error> {
    let cargo_dir_path = Path::new(".cargo");
    if cargo_dir_path.exists() {
        if !cargo_dir_path.is_dir() {
            bail!(
                "fargo wants to create a directory {:#?}, but there is an existing file in the way",
                cargo_dir_path
            );
        }
    } else {
        fs::create_dir(cargo_dir_path)?;
    }

    let mut config = File::create(".cargo/config")?;

    let sysroot_as_path = sysroot_path(target_options)?;
    writeln!(config, "[target.{}]", get_target_triple(target_options))?;
    writeln!(config, "rustflags = \"{}\"", get_rustflags(target_options, &sysroot_as_path)?)?;
    writeln!(
        config,
        "runner = \"{}\"",
        make_fargo_command(None, options, true, target_options, None)?
    )?;
    writeln!(config, "")?;
    writeln!(config, "[build]")?;
    writeln!(config, "rustc = \"{}\"", rustc_path()?.to_string_lossy())?;
    writeln!(config, "rustdoc = \"{}\"", rustdoc_path()?.to_string_lossy())?;
    writeln!(config, "target = \"{}\"", get_target_triple(target_options))?;
    Ok(())
}

static RUN: &str = "run";
static RUN_WITH_TILES: &str = "run-with-tiles";
static RUN_WITH_RUN: &str = "run-with-run";
static RUN_WITH_SESSIONCTL: &str = "run-with-sessionctl";
static STORY_NAME: &str = "story-name";
static MOD_NAME: &str = "mod-name";
static DEFAULT_MOD_NAME: &str = "fargo";

static CHECK: &str = "check";
static RELEASE: &str = "release";
static EXAMPLE: &str = "example";
static EXAMPLES: &str = "examples";

static TEST: &str = "test";
static TEST_TARGET_NAME: &str = "test";
static NOCAPTURE: &str = "nocapture";

static DOC: &str = "doc";
static DOC_OPEN: &str = "open";
static DOC_NO_DEPS: &str = "no-deps";

static X64: &str = "x64";

static SUBCOMMAND: &str = "subcommand";

static DISABLE_CROSS_ENV: &str = "disable-cross-env";

static NO_NET: &str = "no-net";
static FX_RUN_PARAMS: &str = "fx-run-params";
static MANIFEST_PATH: &str = "manifest-path";

static RELEASE_HELP: &str = "Build artifacts in release mode, with optimizations";

static START: &str = "start";
static RESTART: &str = "restart";
static GRAPHICS: &str = "graphics";
static DISABLE_VIRTCON: &str = "disable-virtcon";

static WRITE_CONFIG: &str = "write-config";

static BUILD_RUSTC: &str = "build-rustc";
static RUST_ROOT: &str = "rust-root";

static RUN_ON_TARGET: &str = "run-on-target";

#[doc(hidden)]
pub fn run() -> Result<(), Error> {
    let matches = App::new("fargo")
        .version("v0.2.0")
        .setting(AppSettings::GlobalVersion)
        .setting(AppSettings::ArgRequiredElseHelp)
        .about("Fargo is a prototype Fuchsia-specific wrapper around Cargo")
        .arg(
            Arg::with_name("verbose")
                .long("verbose")
                .short("v")
                .help("Print verbose output while performing commands"),
        )
        .arg(
            Arg::with_name(DISABLE_CROSS_ENV)
                .long(DISABLE_CROSS_ENV)
                .help("Disable the setting of CC, AR and such environmental variables."),
        )
        .arg(
            Arg::with_name("device-name")
                .long("device-name")
                .short("N")
                .value_name("device-name")
                .help(
                    "Name of device to target, needed if there are multiple devices visible \
                     on the network",
                ),
        )
        .arg(
            Arg::with_name(MANIFEST_PATH)
                .long(MANIFEST_PATH)
                .value_name(MANIFEST_PATH)
                .global(true)
                .help("Path to Cargo.toml"),
        )
        .subcommand(
            SubCommand::with_name("autotest")
                .about("Auto build and test in Fuchsia device or emulator")
                .arg(Arg::with_name(RELEASE).long(RELEASE).help("Build release"))
                .arg(
                    Arg::with_name(NOCAPTURE)
                        .long(NOCAPTURE)
                        .help("Display all output when running tests."),
                ),
        )
        .subcommand(
            SubCommand::with_name(TEST)
                .about("Run unit tests on Fuchsia device or emulator")
                .arg(Arg::with_name(RELEASE).long(RELEASE).help(RELEASE_HELP))
                .arg(
                    Arg::with_name(NOCAPTURE)
                        .long(NOCAPTURE)
                        .help("Display all output when running tests."),
                )
                .arg(
                    Arg::with_name(TEST_TARGET_NAME)
                        .long(TEST_TARGET_NAME)
                        .value_name(TEST_TARGET_NAME)
                        .help("Test only the specified test target"),
                )
                .arg(
                    Arg::with_name("package")
                        .short("p")
                        .long("package")
                        .takes_value(true)
                        .help("Package to run tests for"),
                )
                .arg(
                    Arg::with_name("bin")
                        .long("bin")
                        .value_name("bin")
                        .help("Name of the bin target to run"),
                )
                .arg(
                    Arg::with_name("test_args")
                        .long("args")
                        .value_name("args")
                        .help("arguments to pass to the test runner"),
                )
                .arg(Arg::with_name("test_params").index(1).multiple(true)),
        )
        .subcommand(
            SubCommand::with_name("build")
                .about("Build binary targeting Fuchsia device or emulator")
                .arg(Arg::with_name(RELEASE).long(RELEASE).help(RELEASE_HELP))
                .arg(
                    Arg::with_name("package")
                        .short("p")
                        .long("package")
                        .takes_value(true)
                        .help("Package to build"),
                )
                .arg(
                    Arg::with_name("bin")
                        .long("bin")
                        .takes_value(true)
                        .help("Name of the bin target to run"),
                )
                .arg(
                    Arg::with_name("test")
                        .long("test")
                        .takes_value(true)
                        .help("Build only the specified test target"),
                )
                .arg(Arg::with_name("tests").long("tests").help("Build all the tests"))
                .arg(
                    Arg::with_name("example")
                        .long("example")
                        .takes_value(true)
                        .help("Build a specific example from the examples/ dir."),
                )
                .arg(
                    Arg::with_name("examples")
                        .long("examples")
                        .help("Build all examples in the examples/ dir."),
                ),
        )
        .subcommand(
            SubCommand::with_name(CHECK)
                .about("Check binary targeting Fuchsia device or emulator")
                .arg(Arg::with_name(RELEASE).long(RELEASE).help(RELEASE_HELP))
                .arg(
                    Arg::with_name("package")
                        .short("p")
                        .long("package")
                        .takes_value(true)
                        .help("Package to build"),
                )
                .arg(
                    Arg::with_name("bin")
                        .long("bin")
                        .takes_value(true)
                        .help("Name of the bin target to run"),
                )
                .arg(
                    Arg::with_name("test")
                        .long("test")
                        .takes_value(true)
                        .help("Build only the specified test target"),
                )
                .arg(Arg::with_name("tests").long("tests").help("Build all the tests"))
                .arg(
                    Arg::with_name(EXAMPLE)
                        .long(EXAMPLE)
                        .takes_value(true)
                        .help("Check a specific example from the examples/ dir."),
                )
                .arg(
                    Arg::with_name(EXAMPLES)
                        .long(EXAMPLES)
                        .help("Check all examples in the examples/ dir."),
                ),
        )
        .subcommand(
            SubCommand::with_name(DOC)
                .about("Build a package's documentation")
                .arg(Arg::with_name(RELEASE).long(RELEASE).help(RELEASE_HELP))
                .arg(
                    Arg::with_name(DOC_NO_DEPS)
                        .long(DOC_NO_DEPS)
                        .help("Don't build documentation for dependencies"),
                )
                .arg(
                    Arg::with_name(DOC_OPEN)
                        .long(DOC_OPEN)
                        .help("Opens the docs in a browser after the operation"),
                ),
        )
        .subcommand(
            SubCommand::with_name(RUN)
                .about("Run binary on Fuchsia device or emulator")
                .arg(Arg::with_name(RELEASE).long(RELEASE).help(RELEASE_HELP))
                .arg(
                    Arg::with_name(STORY_NAME)
                        .long(STORY_NAME)
                        .short("n")
                        .value_name(STORY_NAME)
                        .help("Name of story to pass to sessionctl"),
                )
                .arg(
                    Arg::with_name(MOD_NAME)
                        .long(MOD_NAME)
                        .short("m")
                        .value_name(MOD_NAME)
                        .help("Name of mod to pass to sessionctl"),
                )
                .arg(
                    Arg::with_name(RUN_WITH_TILES)
                        .long(RUN_WITH_TILES)
                        .help("Use tiles_ctl add to run binary."),
                )
                .arg(Arg::with_name(RUN_WITH_RUN).long(RUN_WITH_RUN).help("Use run to run binary."))
                .arg(
                    Arg::with_name(RUN_WITH_SESSIONCTL)
                        .long(RUN_WITH_SESSIONCTL)
                        .help("Use sessionctl to run binary."),
                )
                .arg(
                    Arg::with_name("package")
                        .short("p")
                        .long("package")
                        .value_name("package")
                        .help("Package to build"),
                )
                .arg(
                    Arg::with_name("bin")
                        .long("bin")
                        .value_name("bin")
                        .help("Name of the bin target to run"),
                )
                .arg(
                    Arg::with_name("example")
                        .long("example")
                        .value_name("example")
                        .help("Run a specific example from the examples/ dir."),
                ),
        )
        .subcommand(
            SubCommand::with_name("load-driver")
                .about("Build driver and load it on Fuchsia device or emulator.")
                .arg(Arg::with_name(RELEASE).long(RELEASE).help("Build release")),
        )
        .subcommand(SubCommand::with_name("list-devices").about("List visible Fuchsia devices"))
        .subcommand(
            SubCommand::with_name(START)
                .about("Start a Fuchsia emulator")
                .arg(
                    Arg::with_name(GRAPHICS)
                        .short("g")
                        .help("Start a simulator with graphics enabled"),
                )
                .arg(
                    Arg::with_name(DISABLE_VIRTCON).long(DISABLE_VIRTCON).help(
                        "Do not launch the virtual console service if this option is present",
                    ),
                )
                .arg(Arg::with_name(NO_NET).long(NO_NET).help("Don't set up networking."))
                .arg(Arg::with_name(FX_RUN_PARAMS).index(1).multiple(true)),
        )
        .subcommand(SubCommand::with_name("stop").about("Stop all Fuchsia emulators"))
        .subcommand(
            SubCommand::with_name("enable-networking")
                .about("Enable networking for a running emulator"),
        )
        .subcommand(
            SubCommand::with_name(RESTART)
                .about("Stop all Fuchsia emulators and start a new one")
                .arg(
                    Arg::with_name(GRAPHICS)
                        .short("g")
                        .help("Start a simulator with graphics enabled"),
                )
                .arg(
                    Arg::with_name(DISABLE_VIRTCON).long(DISABLE_VIRTCON).help(
                        "Do not launch the virtual console service if this option is present",
                    ),
                )
                .arg(Arg::with_name(NO_NET).long(NO_NET).help("Don't set up networking."))
                .arg(Arg::with_name(FX_RUN_PARAMS).index(1).multiple(true)),
        )
        .subcommand(
            SubCommand::with_name("ssh").about("Open a shell on Fuchsia device or emulator"),
        )
        .subcommand(
            SubCommand::with_name("cargo")
                .about(
                    "Run a cargo command for Fuchsia. Use -- to indicate that all following \
                     arguments should be passed to cargo.",
                )
                .arg(Arg::with_name(SUBCOMMAND).required(true))
                .arg(Arg::with_name("cargo_params").index(2).multiple(true)),
        )
        .subcommand(
            SubCommand::with_name(RUN_ON_TARGET)
                .about("Act as a test runner for cargo")
                .arg(
                    Arg::with_name("test_args")
                        .long("args")
                        .value_name("args")
                        .help("arguments to pass to the test runner"),
                )
                .arg(
                    Arg::with_name(NOCAPTURE)
                        .long(NOCAPTURE)
                        .help("Display all output when running tests."),
                )
                .arg(
                    Arg::with_name(RUN_WITH_TILES)
                        .long(RUN_WITH_TILES)
                        .help("Use tiles to run binary."),
                )
                .arg(Arg::with_name(RUN_WITH_RUN).long(RUN_WITH_RUN).help("Use run to run binary."))
                .arg(
                    Arg::with_name(RUN_WITH_SESSIONCTL)
                        .long(RUN_WITH_SESSIONCTL)
                        .help("Use sessionctl to run binary."),
                )
                .arg(
                    Arg::with_name(STORY_NAME)
                        .long(STORY_NAME)
                        .short("n")
                        .value_name(STORY_NAME)
                        .help("Name of story to pass to sessionctl"),
                )
                .arg(
                    Arg::with_name(MOD_NAME)
                        .long(MOD_NAME)
                        .short("m")
                        .value_name(MOD_NAME)
                        .help("Name of mod to pass to sessionctl"),
                )
                .arg(Arg::with_name("run_on_target_params").index(1).multiple(true))
                .setting(AppSettings::Hidden),
        )
        .subcommand(
            SubCommand::with_name("pkg-config")
                .about("Run pkg-config for the cross compilation environment")
                .arg(Arg::with_name("pkgconfig_param").index(1).multiple(true)),
        )
        .subcommand(
            SubCommand::with_name("configure")
                .about("Run a configure script for the cross compilation environment")
                .arg(Arg::with_name("configure_param").index(1).multiple(true))
                .arg(
                    Arg::with_name("no-host")
                        .long("no-host")
                        .help("Don't pass --host to configure"),
                ),
        )
        .subcommand(
            SubCommand::with_name(WRITE_CONFIG).about(
                "Write a .cargo/config file to allow cargo to operate correctly for Fuchsia",
            ),
        )
        .subcommand(
            SubCommand::with_name(BUILD_RUSTC)
                .arg(
                    Arg::with_name(RUST_ROOT)
                        .long(RUST_ROOT)
                        .value_name(RUST_ROOT)
                        .required(true)
                        .help("Path to rust checkout"),
                )
                .about("Build rustc targeting Fuchsia"),
        )
        .get_matches();

    let verbose = matches.is_present("verbose");
    let disable_cross = matches.is_present(DISABLE_CROSS_ENV);

    let fuchsia_config = FuchsiaConfig::new_from_fx_exec()?;
    if verbose {
        println!("fuchsia_config = {:#?}", fuchsia_config);
    }

    let target_options = TargetOptions::new(&fuchsia_config, matches.value_of("device-name"));

    let run_cargo_options = RunCargoOptions {
        verbose,
        release: false,
        nocapture: false,
        run_mode: RunMode::Normal,
        story_name: None,
        mod_name: None,
        disable_cross,
        manifest_path: None,
    };

    if verbose {
        println!("target_options = {:#?}", target_options);
    }

    if let Some(autotest_matches) = matches.subcommand_matches("autotest") {
        let manifest_path = convert_manifest_path(&autotest_matches.value_of(MANIFEST_PATH));
        return autotest(
            &run_cargo_options
                .release(autotest_matches.is_present(RELEASE))
                .manifest_path(manifest_path)
                .nocapture(autotest_matches.is_present(NOCAPTURE)),
            &target_options,
        );
    }

    if let Some(test_matches) = matches.subcommand_matches(TEST) {
        let mut params = vec![];
        if let Some(package) = test_matches.value_of("package") {
            params.push("--package");
            params.push(package);
        }
        if let Some(bin) = test_matches.value_of("bin") {
            params.push("--bin");
            params.push(bin);
        }
        if let Some(test_params) = test_matches.values_of("test_params") {
            params.extend(test_params.collect::<Vec<_>>());
        }
        if let Some(test) = test_matches.value_of(TEST_TARGET_NAME) {
            params.push("--test");
            params.push(test);
        }

        let test_args = test_matches.value_of("test_args");
        let manifest_path = convert_manifest_path(&test_matches.value_of(MANIFEST_PATH));
        return run_tests(
            &run_cargo_options
                .release(test_matches.is_present(RELEASE))
                .manifest_path(manifest_path)
                .nocapture(test_matches.is_present(NOCAPTURE)),
            false,
            &target_options,
            &params,
            test_args,
        );
    }

    if let Some(build_matches) = matches.subcommand_matches("build") {
        let mut params = vec![];
        if let Some(package) = build_matches.value_of("package") {
            params.push("--package");
            params.push(package);
        }
        if let Some(bin) = build_matches.value_of("bin") {
            params.push("--bin");
            params.push(bin);
        }
        if let Some(test) = build_matches.value_of("test") {
            params.push("--test");
            params.push(test);
        }
        if build_matches.is_present("tests") {
            params.push("--tests");
        }
        if let Some(example) = build_matches.value_of("example") {
            params.push("--example");
            params.push(example);
        }
        if build_matches.is_present("examples") {
            params.push("--examples");
        }

        let manifest_path = convert_manifest_path(&build_matches.value_of(MANIFEST_PATH));
        build_binary(
            &run_cargo_options
                .release(build_matches.is_present(RELEASE))
                .manifest_path(manifest_path),
            &target_options,
            &params,
        )?;
        return Ok(());
    }

    if let Some(check_matches) = matches.subcommand_matches(CHECK) {
        let mut params = vec![];
        if let Some(example) = check_matches.value_of(EXAMPLE) {
            params.push("--example");
            params.push(example);
        }
        if let Some(package) = check_matches.value_of("package") {
            params.push("--package");
            params.push(package);
        }
        if let Some(bin) = check_matches.value_of("bin") {
            params.push("--bin");
            params.push(bin);
        }
        if let Some(test) = check_matches.value_of("test") {
            params.push("--test");
            params.push(test);
        }
        if check_matches.is_present("tests") {
            params.push("--tests");
        }
        if check_matches.is_present(EXAMPLES) {
            params.push("--examples");
        }

        let manifest_path = convert_manifest_path(&check_matches.value_of(MANIFEST_PATH));
        check_binary(
            &run_cargo_options
                .release(check_matches.is_present(RELEASE))
                .manifest_path(manifest_path),
            &target_options,
            &params,
        )?;
        return Ok(());
    }

    if let Some(run_matches) = matches.subcommand_matches(RUN) {
        let mut params = vec![];
        if let Some(package) = run_matches.value_of("package") {
            params.push("--package");
            params.push(package);
        }
        if let Some(bin) = run_matches.value_of("bin") {
            params.push("--bin");
            params.push(bin);
        }
        if let Some(example) = run_matches.value_of("example") {
            params.push("--example");
            params.push(example);
        }

        let manifest_path = convert_manifest_path(&run_matches.value_of(MANIFEST_PATH));
        let run_mode = run_switches_to_mode(
            run_matches.is_present(RUN_WITH_TILES),
            run_matches.is_present(RUN_WITH_RUN),
            run_matches.is_present(RUN_WITH_SESSIONCTL),
        );
        return run_binary(
            &run_cargo_options
                .release(run_matches.is_present(RELEASE))
                .run_mode(run_mode)
                .story_name(&run_matches.value_of(STORY_NAME))
                .mod_name(&run_matches.value_of(MOD_NAME))
                .manifest_path(manifest_path),
            &target_options,
            &params,
        );
    }

    if let Some(load_driver_matches) = matches.subcommand_matches("load-driver") {
        return load_driver(
            &run_cargo_options.release(load_driver_matches.is_present(RELEASE)),
            &fuchsia_config,
            &target_options,
        );
    }

    if let Some(doc_matches) = matches.subcommand_matches(DOC) {
        let manifest_path = convert_manifest_path(&doc_matches.value_of(MANIFEST_PATH));
        return build_doc(
            &run_cargo_options
                .release(doc_matches.is_present(RELEASE))
                .manifest_path(manifest_path),
            &target_options,
            doc_matches.is_present(DOC_NO_DEPS),
            doc_matches.is_present(DOC_OPEN),
        );
    }

    if matches.subcommand_matches("list-devices").is_some() {
        return netls(verbose);
    }

    if let Some(start_matches) = matches.subcommand_matches(START) {
        let fx_run_params =
            start_matches.values_of(FX_RUN_PARAMS).map(|x| x.collect()).unwrap_or_else(|| vec![]);

        return start_emulator(
            &StartEmulatorOptions {
                verbose: verbose,
                with_graphics: start_matches.is_present(GRAPHICS),
                with_networking: !start_matches.is_present(NO_NET),
                disable_virtcon: start_matches.is_present(DISABLE_VIRTCON),
            },
            &fx_run_params,
        );
    }

    if matches.subcommand_matches("stop").is_some() {
        return stop_emulator();
    }

    if matches.subcommand_matches("enable-networking").is_some() {
        return enable_networking();
    }

    if let Some(restart_matches) = matches.subcommand_matches(RESTART) {
        stop_emulator()?;

        let fx_run_params =
            restart_matches.values_of(FX_RUN_PARAMS).map(|x| x.collect()).unwrap_or_else(|| vec![]);

        return start_emulator(
            &StartEmulatorOptions {
                verbose: verbose,
                with_graphics: restart_matches.is_present(GRAPHICS),
                with_networking: !restart_matches.is_present(NO_NET),
                disable_virtcon: restart_matches.is_present(DISABLE_VIRTCON),
            },
            &fx_run_params,
        );
    }

    if matches.subcommand_matches("ssh").is_some() {
        return ssh(verbose, &fuchsia_config, &target_options, "");
    }

    if let Some(cargo_matches) = matches.subcommand_matches("cargo") {
        let subcommand =
            cargo_matches.value_of(SUBCOMMAND).expect("The cargo command requires a subcommand");
        let cargo_params =
            cargo_matches.values_of("cargo_params").map(|x| x.collect()).unwrap_or_else(|| vec![]);
        return run_cargo(
            &RunCargoOptions {
                verbose,
                release: false,
                nocapture: false,
                run_mode: RunMode::Normal,
                story_name: None,
                mod_name: None,
                disable_cross: disable_cross,
                manifest_path: None,
            },
            subcommand,
            &cargo_params,
            &target_options,
            None,
            None,
        );
    }

    if let Some(run_on_target_matches) = matches.subcommand_matches(RUN_ON_TARGET) {
        let run_params = run_on_target_matches
            .values_of("run_on_target_params")
            .map(|x| x.collect())
            .unwrap_or_else(|| vec![]);
        let test_args = run_on_target_matches.value_of("test_args");
        let (program, args) =
            run_params.split_first().expect("run on target expects at least one parameter");
        let run_mode = run_switches_to_mode(
            run_on_target_matches.is_present(RUN_WITH_TILES),
            run_on_target_matches.is_present(RUN_WITH_RUN),
            run_on_target_matches.is_present(RUN_WITH_SESSIONCTL),
        );
        return run_program_on_target(
            program,
            verbose,
            run_on_target_matches.is_present(NOCAPTURE),
            &fuchsia_config,
            &target_options,
            run_mode,
            run_on_target_matches.value_of(STORY_NAME).unwrap_or(&random_story_name()),
            run_on_target_matches.value_of(MOD_NAME).unwrap_or(DEFAULT_MOD_NAME),
            args,
            test_args,
        );
    }

    if let Some(pkg_matches) = matches.subcommand_matches("pkg-config") {
        let pkg_params =
            pkg_matches.values_of("pkgconfig_param").map(|x| x.collect()).unwrap_or_else(|| vec![]);
        let exit_code = run_pkg_config(verbose, &pkg_params, &target_options)?;
        if exit_code != 0 {
            ::std::process::exit(exit_code);
        }
        return Ok(());
    }

    if let Some(configure_matches) = matches.subcommand_matches("configure") {
        let configure_params = configure_matches
            .values_of("configure_param")
            .map(|x| x.collect())
            .unwrap_or_else(|| vec![]);
        run_configure(
            verbose,
            !configure_matches.is_present("no-host"),
            &configure_params,
            &target_options,
        )?;
        return Ok(());
    }

    if let Some(_write_config_matches) = matches.subcommand_matches(WRITE_CONFIG) {
        return write_config(&run_cargo_options, &target_options);
    }

    if let Some(build_rustc_matches) = matches.subcommand_matches(BUILD_RUSTC) {
        let rust_root = PathBuf::from(
            build_rustc_matches
                .value_of(RUST_ROOT)
                .expect("rust_root is a required parameter of build-rustc"),
        );
        return build_rustc(&rust_root, &target_options);
    }

    Ok(())
}
