// 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 cross;
mod device;
mod sdk;
mod utils;

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

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

use clap::{App, AppSettings, Arg, SubCommand};
use failure::{bail, err_msg, 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().unwrap().to_string_lossy()
    );
    println!(
        "copying {} to {}",
        source_path.to_string_lossy(),
        destination_path
    );
    scp_to_device(verbose, config, &netaddr, &source_path, &destination_path)?;
    Ok(destination_path)
}

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

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

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

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

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

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

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

extern crate notify;

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

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

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

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

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

fn build_tests(
    run_cargo_options: &RunCargoOptions, target_options: &TargetOptions<'_, '_>, test_target: &str,
) -> Result<bool, Error> {
    run_tests(
        run_cargo_options,
        true,
        target_options,
        test_target,
        &[],
        None,
    )?;
    Ok(true)
}

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

    if !test_target.is_empty() {
        args.push("--test");
        args.push(test_target);
    }

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

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

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

    Ok(())
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Ok(rust_flags.join(" "))
}

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

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

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

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

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

    runner_args.push(RUN_ON_TARGET);

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

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

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

    Ok(runner_args.join(" "))
}

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

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

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

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

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

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

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

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

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

    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_str().unwrap());
        println!("cargo_path: {:?}", cargo_path()?.to_str().unwrap());
    }

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

    if let Some(ref manifest_path) = options.manifest_path {
        let manifest_args: Vec<&str> = vec!["--manifest-path", manifest_path.to_str().unwrap()];
        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_str().unwrap())
            .env(cxx_env_name, clang_cpp_compiler_path()?.to_str().unwrap())
            .env(cflags_env_name, format!("--sysroot={}", sysroot_as_str))
            .env(ar_env_name, clang_archiver_path()?.to_str().unwrap())
            .env("RANLIB", clang_ranlib_path()?.to_str().unwrap())
            .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_str().unwrap())?;
    writeln!(
        config,
        "rustdoc = \"{}\"",
        rustdoc_path()?.to_str().unwrap()
    )?;
    writeln!(config, "target = \"{}\"", get_target_triple(target_options))?;
    Ok(())
}

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

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

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

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

static X64: &str = "x64";

static SUBCOMMAND: &str = "subcommand";

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

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

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

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

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

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

#[doc(hidden)]
pub fn run() -> Result<(), Error> {
    let matches =
        App::new("fargo")
            .version("v0.2.0")
            .setting(AppSettings::GlobalVersion)
            .about("Fargo is a prototype Fuchsia-specific wrapper around Cargo")
            .arg(
                Arg::with_name("verbose")
                    .long("verbose")
                    .short("v")
                    .help("Print verbose output while performing commands"),
            )
            .arg(
                Arg::with_name(DISABLE_CROSS_ENV)
                    .long(DISABLE_CROSS_ENV)
                    .help("Disable the setting of CC, AR and such environmental variables."),
            )
            .arg(
                Arg::with_name("device-name")
                    .long("device-name")
                    .short("N")
                    .value_name("device-name")
                    .help(
                        "Name of device to target, needed if there are multiple devices visible \
                         on the network",
                    ),
            )
            .arg(
                Arg::with_name(MANIFEST_PATH)
                    .long(MANIFEST_PATH)
                    .value_name(MANIFEST_PATH)
                    .global(true)
                    .help("Path to Cargo.toml"),
            )
            .subcommand(
                SubCommand::with_name("autotest")
                    .about("Auto build and test in Fuchsia device or emulator")
                    .arg(Arg::with_name(RELEASE).long(RELEASE).help("Build release"))
                    .arg(
                        Arg::with_name(NOCAPTURE)
                            .long(NOCAPTURE)
                            .help("Display all output when running tests."),
                    ),
            )
            .subcommand(
                SubCommand::with_name("build-tests")
                    .about("Build tests for Fuchsia device or emulator")
                    .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(RELEASE).long(RELEASE).help("Build release")),
            )
            .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("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("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(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("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",
            ))
            .get_matches();

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

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

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

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

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

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

    if let Some(test_matches) = matches.subcommand_matches(TEST) {
        let test_params = test_matches
            .values_of("test_params")
            .map(|x| x.collect())
            .unwrap_or_else(|| vec![]);
        let test_target = test_matches.value_of(TEST_TARGET_NAME).unwrap_or("");
        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,
            test_target,
            &test_params,
            test_args,
        );
    }

    if let Some(build_matches) = matches.subcommand_matches("build") {
        let mut params = vec![];
        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 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(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(build_test_matches) = matches.subcommand_matches("build-tests") {
        let test_target = build_test_matches.value_of(TEST_TARGET_NAME).unwrap_or("");
        let manifest_path = convert_manifest_path(&build_test_matches.value_of(MANIFEST_PATH));
        build_tests(
            &run_cargo_options
                .release(build_test_matches.is_present(RELEASE))
                .manifest_path(manifest_path),
            &target_options,
            test_target,
        )?;
        return Ok(());
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Ok(())
}
