// 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 package;
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::package::make_package;
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,
    },
    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,
    cmx_path: &Option<PathBuf>,
    story_name: &str,
    mod_name: &str,
    params: &[&str],
    test_args: Option<&str>,
) -> Result<(), Error> {
    let source_path = PathBuf::from(&filename);
    let target_string = match run_mode {
        RunMode::Normal => {
            let stripped_source_path = strip_binary(&source_path)?;
            copy_to_target(&stripped_source_path, verbose, config, target_options)?
        }
        _ => {
            if cmx_path.is_none() {
                bail!("Run modes other than normal require a path to a cmx file");
            }
            make_package(target_options, &source_path, cmx_path.as_ref().unwrap())?
        }
    };

    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(&target_string);

    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).context("ssh failed")?;
    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,
}

impl Default for RunMode {
    fn default() -> Self {
        RunMode::Normal
    }
}
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, Clone, Default)]
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>,
    pub cmx_path: Option<PathBuf>,
}

impl RunCargoOptions {
    pub fn new(verbose: bool, release: bool) -> RunCargoOptions {
        Self { verbose, release, ..Self::default() }
    }

    pub fn disable_cross(&self, disable_cross: bool) -> RunCargoOptions {
        Self { disable_cross, ..self.clone() }
    }

    pub fn release(&self, release: bool) -> RunCargoOptions {
        Self { release, ..self.clone() }
    }

    pub fn nocapture(&self, nocapture: bool) -> RunCargoOptions {
        Self { nocapture, ..self.clone() }
    }

    pub fn run_mode(&self, run_mode: RunMode) -> RunCargoOptions {
        Self { run_mode, ..self.clone() }
    }

    pub fn story_name(&self, story_name: &Option<&str>) -> RunCargoOptions {
        Self { story_name: story_name.map(|name| name.to_string()), ..self.clone() }
    }

    pub fn mod_name(&self, mod_name: &Option<&str>) -> RunCargoOptions {
        Self { mod_name: mod_name.map(|name| name.to_string()), ..self.clone() }
    }

    pub fn manifest_path(&self, manifest_path: Option<PathBuf>) -> RunCargoOptions {
        Self { manifest_path, ..self.clone() }
    }

    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()
        }
    }
}

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

pub 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 zircon_build_dir = zircon_build_path(&target_options.config)?;
    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{}/user-{}-gcc.shlib/obj/system/ulib/fdio",
            zircon_build_dir.to_string_lossy(),
            target_options.config.fuchsia_arch
        ),
        format!(
            "-Clink-arg=-L{}/user-{}-gcc.shlib/obj/system/ulib/syslog",
            zircon_build_dir.to_string_lossy(),
            target_options.config.fuchsia_arch
        ),
        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 mut cmx_path;
    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 cmx_arg = format!("--{}", CMX_PATH);
    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);
    }

    if let Some(ref passed_path) = options.cmx_path {
        cmx_path = passed_path.to_string_lossy().to_string();
        runner_args.push(&cmx_arg);
        runner_args.push(&cmx_path);
    } else {
        match options.run_mode {
            RunMode::Normal => (),
            _ => {
                bail!("Run modes other than normal require a path to a cmx file");
            }
        }
    }

    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,
///         cmx_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.config)?)
        .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 CMX_PATH: &str = "cmx-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";

static MAKE_PACKAGE: &str = "make-package";
static BINARY_PATH: &str = "binary-path";

#[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"),
        )
        .arg(
            Arg::with_name(CMX_PATH)
                .long(CMX_PATH)
                .value_name(CMX_PATH)
                .help("Path to sandbox file to use when running"),
        )
        .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"),
        )
        .subcommand(
            SubCommand::with_name(MAKE_PACKAGE)
                .arg(
                    Arg::with_name(BINARY_PATH)
                        .long(BINARY_PATH)
                        .value_name(BINARY_PATH)
                        .required(true)
                        .help("Path to the binary to package"),
                )
                .about("Make a Fuchsia package from an unstripped binary"),
        )
        .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,
        cmx_path: matches.value_of(CMX_PATH).map(|s| PathBuf::from(s)),
        ..RunCargoOptions::default()
    };

    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, &target_options);
    }

    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,
                cmx_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_cargo_options.cmx_path,
            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);
    }

    if let Some(make_package_matches) = matches.subcommand_matches(MAKE_PACKAGE) {
        let binary_path = PathBuf::from(
            make_package_matches
                .value_of(BINARY_PATH)
                .expect(&format!("{} is a required parameter of {}", BINARY_PATH, MAKE_PACKAGE)),
        );
        let cmx_path = PathBuf::from(
            make_package_matches
                .value_of(CMX_PATH)
                .expect(&format!("{} is a required parameter of {}", CMX_PATH, MAKE_PACKAGE)),
        );
        println!("make package {}", make_package(&target_options, &binary_path, &cmx_path)?);
        return Ok(());
    }

    Ok(())
}
