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

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

#![recursion_limit = "1024"]

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

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

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

use clap::{App, AppSettings, Arg, SubCommand};
use failure::{bail, err_msg, 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 BUILD_RUSTC: &str = "build-rustc";
static RUST_ROOT: &str = "rust-root";

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

#[doc(hidden)]
pub fn run() -> Result<(), Error> {
    let matches =
        App::new("fargo")
            .version("v0.2.0")
            .setting(AppSettings::GlobalVersion)
            .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",
            ))
            .subcommand(
                SubCommand::with_name(BUILD_RUSTC)
                    .arg(
                        Arg::with_name(RUST_ROOT)
                            .long(RUST_ROOT)
                            .value_name(RUST_ROOT)
                            .required(true)
                            .help("Path to rust checkout"),
                    )
                    .about("Build rustc targeting Fuchsia"),
            )
            .get_matches();

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

    let fuchsia_config = FuchsiaConfig::new()?;
    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);
    }

    if let Some(build_rustc_matches) = matches.subcommand_matches(BUILD_RUSTC) {
        let rust_root = PathBuf::from(build_rustc_matches.value_of(RUST_ROOT).unwrap());
        return build_rustc(&rust_root, &target_options);
    }

    Ok(())
}
