// 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,
    app_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(
                verbose,
                target_options,
                &source_path,
                cmx_path.as_ref().unwrap(),
                app_name,
            )?
        }
    };

    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>,
    pub app_name: Option<String>,
}

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 cmx_path(&self, cmx_path: Option<PathBuf>) -> RunCargoOptions {
        Self { cmx_path, ..self.clone() }
    }

    pub fn app_name(&self, app_name: &Option<&str>) -> RunCargoOptions {
        Self { app_name: app_name.map(|name| name.to_string()), ..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 sysroot_lib_pathbuf = sysroot_as_path.join("lib");
    let sysroot_lib = sysroot_lib_pathbuf.to_string_lossy();
    let shared_lib_path = shared_libraries_path(target_options)?;
    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{}/gen/zircon/public/lib/fdio", shared_lib_path.to_string_lossy(),),
        format!("-Clink-arg=-L{}/gen/zircon/public/lib/syslog", shared_lib_path.to_string_lossy(),),
        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 app_name_arg = format!("--{}", APP_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 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");
            }
        }
    }

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

    if let Some(app_name) = options.app_name.as_ref() {
        runner_args.push(&app_name_arg);
        runner_args.push(&app_name);
    }

    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 APP_NAME: &str = "app-name";
static DEFAULT_APP_NAME: &str = "app";

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 KVM: &str = "kvm";
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";

/// Arguments which configure the startup of an emulator.
///
/// Used when `start`ing or `restart`ing.
fn emulator_args() -> Vec<Arg<'static, 'static>> {
    vec![
        Arg::with_name(GRAPHICS).short("g").help("Start a simulator with graphics enabled"),
        Arg::with_name(KVM).short("k").help("Start a simulator with KVM (Linux only)"),
        Arg::with_name(DISABLE_VIRTCON)
            .long(DISABLE_VIRTCON)
            .help("Do not launch the virtual console service if this option is present"),
        Arg::with_name(NO_NET).long(NO_NET).help("Don't set up networking."),
        Arg::with_name(FX_RUN_PARAMS).index(1).multiple(true),
    ]
}

#[doc(hidden)]
pub fn run() -> Result<(), Error> {
    let emulator_args = emulator_args();

    let global_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(CMX_PATH)
                        .long(CMX_PATH)
                        .value_name(CMX_PATH)
                        .help("Path to sandbox file to use when running"),
                )
                .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(CMX_PATH)
                        .long(CMX_PATH)
                        .value_name(CMX_PATH)
                        .help("Path to sandbox file to use when running"),
                )
                .arg(Arg::with_name(RUN_WITH_RUN).long(RUN_WITH_RUN).help("Use run to run tests."))
                .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(APP_NAME)
                        .long(APP_NAME)
                        .value_name(APP_NAME)
                        .default_value(DEFAULT_APP_NAME)
                        .help("Name of app as it appears in the manifest file."),
                )
                .arg(
                    Arg::with_name(CMX_PATH)
                        .long(CMX_PATH)
                        .value_name(CMX_PATH)
                        .help("Path to sandbox file to use when running"),
                )
                .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").args(&emulator_args),
        )
        .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")
                .args(&emulator_args),
        )
        .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(CMX_PATH)
                        .long(CMX_PATH)
                        .value_name(CMX_PATH)
                        .help("Path to sandbox file to use when running"),
                )
                .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(APP_NAME)
                        .long(APP_NAME)
                        .value_name(APP_NAME)
                        .default_value(DEFAULT_APP_NAME)
                        .help("Name of app"),
                )
                .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"),
                )
                .arg(
                    Arg::with_name(CMX_PATH)
                        .long(CMX_PATH)
                        .value_name(CMX_PATH)
                        .help("Path to sandbox file to use when running"),
                )
                .arg(
                    Arg::with_name(APP_NAME)
                        .long(APP_NAME)
                        .value_name(APP_NAME)
                        .default_value(DEFAULT_APP_NAME)
                        .help("Name of app"),
                )
                .about("Make a Fuchsia package from an unstripped binary"),
        )
        .get_matches();

    let verbose = global_matches.is_present("verbose");
    let disable_cross = global_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, global_matches.value_of("device-name"));

    let run_cargo_options = RunCargoOptions { verbose, ..RunCargoOptions::default() };

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

    if let Some(autotest_matches) = global_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)
                .cmx_path(autotest_matches.value_of(CMX_PATH).map(|s| PathBuf::from(s)))
                .nocapture(autotest_matches.is_present(NOCAPTURE)),
            &target_options,
        );
    }

    if let Some(test_matches) = global_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));
        let run_mode = run_switches_to_mode(
            test_matches.is_present(RUN_WITH_TILES),
            test_matches.is_present(RUN_WITH_RUN),
            test_matches.is_present(RUN_WITH_SESSIONCTL),
        );
        return run_tests(
            &run_cargo_options
                .cmx_path(test_matches.value_of(CMX_PATH).map(|s| PathBuf::from(s)))
                .run_mode(run_mode)
                .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) = global_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) = global_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) = global_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))
                .app_name(&run_matches.value_of(APP_NAME))
                .manifest_path(manifest_path)
                .cmx_path(run_matches.value_of(CMX_PATH).map(|s| PathBuf::from(s))),
            &target_options,
            &params,
        );
    }

    if let Some(load_driver_matches) = global_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) = global_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 global_matches.subcommand_matches("list-devices").is_some() {
        return netls(verbose, &target_options);
    }

    if let Some(start_matches) = global_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_kvm: start_matches.is_present(KVM),
                with_networking: !start_matches.is_present(NO_NET),
                disable_virtcon: start_matches.is_present(DISABLE_VIRTCON),
            },
            &fx_run_params,
        );
    }

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

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

    if let Some(restart_matches) = global_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_kvm: restart_matches.is_present(KVM),
                with_networking: !restart_matches.is_present(NO_NET),
                disable_virtcon: restart_matches.is_present(DISABLE_VIRTCON),
            },
            &fx_run_params,
        );
    }

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

    if let Some(cargo_matches) = global_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,
                app_name: None,
            },
            subcommand,
            &cargo_params,
            &target_options,
            None,
            None,
        );
    }

    if let Some(run_on_target_matches) = global_matches.subcommand_matches(RUN_ON_TARGET) {
        let run_cargo_options = run_cargo_options
            .cmx_path(run_on_target_matches.value_of(CMX_PATH).map(|s| PathBuf::from(s)));

        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),
            run_on_target_matches.value_of(APP_NAME).unwrap_or(DEFAULT_APP_NAME),
            args,
            test_args,
        );
    }

    if let Some(pkg_matches) = global_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) = global_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) = global_matches.subcommand_matches(WRITE_CONFIG) {
        return write_config(&run_cargo_options, &target_options);
    }

    if let Some(build_rustc_matches) = global_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) = global_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(verbose, &target_options, &binary_path, &cmx_path, "app")?
        );
        return Ok(());
    }

    Ok(())
}
