// 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.

#![deny(warnings)]

mod build_rustc;
pub mod command_line;
mod cross;
mod device;
mod linking;
mod manifest;
mod package;
mod sdk;
mod utils;

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

use crate::cross::{pkg_config_path, run_configure};
use crate::device::{enable_networking, ffx, shell};
use crate::package::make_package;
use crate::sdk::{
    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, target_out_dir,
};
use manifest::Manifest;

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 run_program_on_target(
    filename: &str,
    verbose: bool,
    nocapture: bool,
    target_options: &TargetOptions<'_, '_>,
    run_mode: RunMode,
    run_cargo_options: &RunCargoOptions,
    app_dir: &str,
    app_name: &str,
    params: &[&str],
    test_args: Option<&str>,
) -> Result<(), Error> {
    let source_path = PathBuf::from(&filename);

    let target_string =
        make_package(verbose, target_options, &run_cargo_options, &source_path, app_dir, app_name)?;

    let mut command_string = match run_mode {
        RunMode::Tiles => "tiles_ctl add ".to_string(),
        RunMode::SessionControl => {
            format!("session_control add ")
        }
        RunMode::Run => "run ".to_string(),
        RunMode::FfxComponent => "component run ".to_string(),
    };
    command_string.push_str(&target_string);

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

    match run_mode {
        RunMode::FfxComponent => ffx(verbose, &command_string).context("ssh failed")?,
        _ => shell(verbose, target_options, &command_string).context("ssh failed")?,
    }
    Ok(())
}

extern crate notify;

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

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

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

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

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

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

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

    if doc {
        args.push("--doc");
    }

    if lib {
        args.push("--lib");
    }

    if bins {
        args.push("--bins");
    }

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

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

    Ok(())
}

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

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

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

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

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

impl Default for RunMode {
    fn default() -> Self {
        RunMode::Run
    }
}
fn run_switches_to_mode(ffx: bool, tiles: bool, session_control: bool) -> RunMode {
    if tiles {
        RunMode::Tiles
    } else if session_control {
        RunMode::SessionControl
    } else if ffx {
        RunMode::FfxComponent
    } else {
        RunMode::Run
    }
}

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

#[derive(Debug, Clone, Default)]
pub struct RunCargoOptions {
    pub fargo_manifest: Manifest,
    pub verbose: bool,
    pub release: bool,
    pub linking: bool,
    pub run_mode: RunMode,
    pub story_name: Option<String>,
    pub mod_name: Option<String>,
    pub disable_cross: bool,
    pub nocapture: bool,
    pub manifest_path: Option<PathBuf>,
    pub sandbox_file_path: Option<PathBuf>,
    pub app_dir: Option<String>,
    pub app_name: Option<String>,
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

pub fn get_vdso_path(target_options: &TargetOptions<'_, '_>) -> Result<PathBuf, Error> {
    let vdso_name =
        if target_options.config.fuchsia_arch == X64 { "user.vdso_x64" } else { "user.vdso_arm64" }
            .to_string();
    Ok(target_out_dir(target_options.config)?.join(vdso_name))
}

pub fn get_user_libc_path(target_options: &TargetOptions<'_, '_>) -> Result<PathBuf, Error> {
    let libc_name =
        if target_options.config.fuchsia_arch == X64 { "user.libc_x64" } else { "user.libc_arm64" }
            .to_string();
    Ok(target_out_dir(target_options.config)?.join(libc_name))
}

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

    let mut rust_flags = vec![
        "-L".to_string(),
        sysroot_lib.to_string(),
        "-Cpanic=abort".to_string(),
        "-Zpanic_abort_tests".to_string(),
        // Add an extra config to let crates like scoped_task know we're compiling with
        // panic=abort. This matches
        // http://fuchsia.googlesource.com/fuchsia/+/08dce526941ac5be23cec1b50f841aad5ed37ea1/build/config/BUILD.gn#547
        "--cfg=rust_panic=\"abort\"".to_string(),
        "-Clink-arg=--pack-dyn-relocs=relr".to_string(),
        "-Clink-args=-zstack-size=0x200000".to_string(),
        format!("-Clink-arg=-L{}", sysroot_lib),
        format!("-Clink-arg=-L{}/gen/zircon/public/lib/fdio", shared_lib_path.to_string_lossy(),),
        format!("-Clink-arg=-L{}/gen/zircon/public/lib/syslog", shared_lib_path.to_string_lossy(),),
        format!(
            "-Clink-arg=-L{}/gen/zircon/public/lib/trace-engine",
            shared_lib_path.to_string_lossy(),
        ),
        format!("-Clink-arg=-L{}", clang_resource_lib.to_string_lossy()),
        format!("-Clink-arg=-L{}", target_out_dir(target_options.config)?.to_string_lossy()),
        format!("-Clink-arg=-L{}", get_vdso_path(target_options)?.to_string_lossy()),
        format!("-Clink-arg=--sysroot={}", sysroot_as_path.to_string_lossy()),
        format!(
            "-Clink-arg={}/obj/zircon/system/ulib/c/crt1.Scrt1.cc.o",
            get_user_libc_path(target_options)?.to_string_lossy()
        ),
        format!("-Lnative={}", shared_libraries_path(target_options)?.to_string_lossy()),
    ];

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

    for search_path in &run_cargo_options.fargo_manifest.library_search_paths {
        let full_search_path = target_out_dir(&target_options.config)?.join(search_path);
        let arg = format!("-Lnative={}", full_search_path.to_string_lossy());
        rust_flags.push(arg);
    }

    if linking {
        for additional_lib in &run_cargo_options.fargo_manifest.additional_static_libraries {
            let arg = format!("-l{}", additional_lib);
            rust_flags.push(arg);
        }
    }

    Ok(rust_flags.join(" "))
}

fn make_absolute(path: &Path) -> Result<PathBuf, Error> {
    if path.is_absolute() {
        Ok(path.to_path_buf())
    } else {
        Ok(std::env::current_dir()?.join(path))
    }
}

fn make_fargo_command(
    runner: Option<PathBuf>,
    options: &RunCargoOptions,
    nocapture: bool,
    target_options: &TargetOptions<'_, '_>,
    additional_target_args: Option<&str>,
) -> Result<String, Error> {
    let sandbox_file_path;
    let tiles_arg = format!("--{}", RUN_WITH_TILES);
    let session_control_arg = format!("--{}", RUN_WITH_SESSION_CONTROL,);
    let manifest_path_absolute;
    let manifest_path_string;
    let sandbox_file_arg = format!("--{}", SANDBOX_FILE_PATH);
    let app_dir_arg = format!("--{}", APP_DIR);
    let app_name_arg = format!("--{}", APP_NAME);
    let run_arg = format!("--{}", RUN_WITH_RUN);
    let run_with_ffx_component_arg = format!("--{}", RUN_WITH_FFX_COMP);
    let nocapture_arg = format!("--{}", NOCAPTURE);

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

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

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

    if let Some(manifest_path) = options.manifest_path.as_ref() {
        manifest_path_absolute = make_absolute(manifest_path)?;
        manifest_path_string = manifest_path_absolute.to_string_lossy();
        runner_args.push("--manifest-path");
        runner_args.push(&manifest_path_string);
    }

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

    runner_args.push(RUN_ON_TARGET);

    if let Some(ref passed_path) = options.sandbox_file_path {
        sandbox_file_path = passed_path.to_string_lossy().to_string();
        runner_args.push(&sandbox_file_arg);
        runner_args.push(&sandbox_file_path);
    }

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

    match options.run_mode {
        RunMode::Tiles => runner_args.push(&tiles_arg),
        RunMode::SessionControl => runner_args.push(&session_control_arg),
        RunMode::Run => runner_args.push(&run_arg),
        RunMode::FfxComponent => runner_args.push(&run_with_ffx_component_arg),
    }

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

    if let Some(app_dir) = options.app_dir.as_ref() {
        runner_args.push(&app_dir_arg);
        runner_args.push(&app_dir);
    }

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

    Ok(runner_args.join(" "))
}

fn format_project(manifest_path: Option<PathBuf>) -> Result<(), Error> {
    let mut cmd = Command::new(cargo_path()?);
    if let Some(ref manifest_path) = manifest_path {
        let parent =
            manifest_path.parent().expect(&format!("Can't get parent of {:#?}", manifest_path));
        cmd.current_dir(parent);
    }
    cmd.arg(FORMAT);
    let cargo_status = cmd.status()?;
    if !cargo_status.success() {
        bail!("cargo exited with status {:?}", cargo_status,);
    }
    Ok(())
}

/// 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::Run,
///         ..RunCargoOptions::default()
///     },
///     "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()?);

    if options.verbose {
        cmd.arg("-v");
    }

    let sysroot_as_path = sysroot_path(target_options)?;
    let sysroot_as_str = sysroot_as_path.to_string_lossy();

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

    let runner_env_name = format!("CARGO_TARGET_{}_RUNNER", target_triple_uc);
    let rustflags_env_name = format!("CARGO_TARGET_{}_RUSTFLAGS", target_triple_uc);
    let rustflags = get_rustflags(options, target_options, &sysroot_as_path, options.linking)?;

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

    cmd.env(runner_env_name, fargo_command)
        .env(rustflags_env_name, &rustflags)
        .env("RUSTC", rustc_path()?.to_string_lossy().as_ref())
        .env("RUSTDOC", rustdoc_path()?.to_string_lossy().as_ref())
        .env("RUSTDOCFLAGS", &rustflags)
        .env("FUCHSIA_SHARED_ROOT", shared_libraries_path(target_options)?)
        .arg(subcommand)
        .args(target_args)
        .args(args);

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

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

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

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

    Ok(())
}

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

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

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

const RUN: &str = "run";
const RUN_WITH_TILES: &str = "run-with-tiles";
const RUN_WITH_RUN: &str = "run-with-run";
const RUN_WITH_FFX_COMP: &str = "run-with-ffx-component";
const RUN_WITH_SESSION_CONTROL: &str = "run-with-session-control";
const DEFAULT_MOD_NAME: &str = "fargo";
const APP_DIR: &str = "app-dir";
const APP_NAME: &str = "app-name";

const BUILD: &str = "build";
const TEST: &str = "test";

const NOCAPTURE: &str = "nocapture";

const X64: &str = "x64";

const SANDBOX_FILE_PATH: &str = "sandbox-file-path";

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

const FORMAT: &str = "fmt";
