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

use crate::{
    get_user_libc_path,
    sdk::{
        amber_path, cmc_path, fuchsia_dir, package_manager_path, shared_libraries_path,
        FuchsiaConfig, TargetOptions,
    },
    target_out_dir,
    utils::{strip_binary, target_crate_path},
    RunCargoOptions,
};
use failure::{bail, ensure, format_err, Error, ResultExt};
use serde::{Deserialize, Serialize};
use serde_json::json;
use std::{
    collections::HashMap,
    fs::{create_dir_all, File},
    io::Write,
    path::{Path, PathBuf},
    process::Command,
};
use tempfile::{tempdir, TempDir};

#[derive(Serialize, Deserialize)]
struct Sandbox {
    services: Vec<String>,
}
#[derive(Serialize, Deserialize)]

struct SandboxFile {
    program: HashMap<String, String>,
    sandbox: Sandbox,
}

fn default_sandbox_file(temp_dir: &TempDir) -> Result<PathBuf, Error> {
    let path = temp_dir.path().join("default.cmx");

    // fuchsia.process.Launcher is required by -Zpanic_abort_tests, which fargo sets
    let services = vec!["fuchsia.process.Launcher"].iter().map(|s| String::from(*s)).collect();
    let sandbox = Sandbox { services };
    let mut program = HashMap::new();
    program.insert("binary".to_string(), "bin/app".to_string());
    let sandbox_file = SandboxFile { program, sandbox };
    let serialized_sandbox_file = serde_json::to_string(&sandbox_file).expect("serialized");
    let mut temp_sandbox_file = File::create(&path)?;
    writeln!(temp_sandbox_file, "{}", serialized_sandbox_file)?;
    Ok(path)
}

pub fn is_v2_sandbox_file(cmx_or_cml_path: &Path) -> Result<bool, Error> {
    match cmx_or_cml_path
        .extension()
        .expect("Failed to get sandbox file extension")
        .to_str()
        .expect("Failed to convert sandbox file extension to str")
    {
        "cmx" => Ok(false),
        "cml" => Ok(true),
        other => bail!("Unrecognized sandbox file extension '{}', expected .cmx or .cml", other),
    }
}

fn validate_cmx_file(
    verbose: bool,
    fuchsia_config: &FuchsiaConfig,
    cmx_path: &Path,
) -> Result<(), Error> {
    if verbose {
        println!("validate_cmx_file: cmx_path = {:#?}", cmx_path);
    }

    ensure!(cmx_path.exists(), "No file at {}", cmx_path.to_string_lossy());

    let cmc = cmc_path(fuchsia_config)?;

    let output = Command::new(cmc)
        .arg("validate")
        .arg(cmx_path)
        .output()
        .context("Running `cmc` to validate cmx file")?;

    if !output.status.success() {
        bail!("cmc returned error: {}", String::from_utf8_lossy(&output.stderr));
    }

    Ok(())
}

fn compile_cml_file(
    verbose: bool,
    fuchsia_config: &FuchsiaConfig,
    cml_path: &Path,
    temp_dir: &TempDir,
) -> Result<PathBuf, Error> {
    if verbose {
        println!("compile_cml_file: cml_path = {:#?}", cml_path);
    }

    ensure!(cml_path.exists(), "No file at {}", cml_path.to_string_lossy());

    let temp_dir_str = temp_dir.path().to_string_lossy();
    let destination_path = format!(
        "{}/compiled_{}",
        temp_dir_str,
        cml_path
            .with_extension("cm")
            .file_name()
            .ok_or(format_err!("file_name failed on {:#?}", cml_path))?
            .to_string_lossy()
    );

    let cmc = cmc_path(fuchsia_config)?;
    let fuchsia_dir = &fuchsia_dir()?;

    let output = Command::new(cmc)
        .arg("compile")
        .arg(cml_path)
        .arg("--output")
        .arg(&destination_path)
        .arg("--includepath")
        .arg(&fuchsia_dir)
        .arg("--includeroot")
        .arg(&fuchsia_dir)
        .output()
        .context("Running `cmc` to compile cml file")?;

    if !output.status.success() {
        if verbose {
            println!("cmc output: {}", String::from_utf8_lossy(&output.stdout));
        }
        println!("cmc returned error: {}", String::from_utf8_lossy(&output.stderr));
        bail!("cmc returned error: {}", String::from_utf8_lossy(&output.stderr));
    }

    Ok(PathBuf::from(destination_path))
}

fn include_cmx_or_cml_file(
    verbose: bool,
    fuchsia_config: &FuchsiaConfig,
    cmx_or_cml_path: &Path,
    temp_dir: &TempDir,
) -> Result<PathBuf, Error> {
    if verbose {
        println!("include_cmx_or_cml_file: cmx_or_cml_path = {:#?}", cmx_or_cml_path);
    }

    ensure!(cmx_or_cml_path.exists(), "No file at {}", cmx_or_cml_path.to_string_lossy());

    let temp_dir_str = temp_dir.path().to_string_lossy();
    let destination_path = format!(
        "{}/included_{}",
        temp_dir_str,
        cmx_or_cml_path
            .file_name()
            .ok_or(format_err!("file_name failed on {:#?}", cmx_or_cml_path))?
            .to_string_lossy()
    );

    let cmc = cmc_path(fuchsia_config)?;
    let fuchsia_dir = &fuchsia_dir()?;
    let sdk_dir = fuchsia_dir.join("sdk").join("lib");

    let output = Command::new(cmc)
        .arg("include")
        .arg(cmx_or_cml_path)
        .arg("--output")
        .arg(&destination_path)
        .arg("--includepath")
        .arg(&sdk_dir)
        .arg("--includeroot")
        .arg(&fuchsia_dir)
        .output()
        .context("Running `cmc` to resolve includes cmx file")?;

    if !output.status.success() {
        if verbose {
            println!("cmc output: {}", String::from_utf8_lossy(&output.stdout));
        }
        bail!("cmc returned error: {}", String::from_utf8_lossy(&output.stderr));
    }

    Ok(PathBuf::from(destination_path))
}

fn format_cmx_file(
    verbose: bool,
    fuchsia_config: &FuchsiaConfig,
    cmx_path: &Path,
    temp_dir: &TempDir,
) -> Result<PathBuf, Error> {
    ensure!(cmx_path.exists(), "No file at {}", cmx_path.to_string_lossy());
    if verbose {
        println!("format_cmx_file: cmx_path = {:#?}", cmx_path);
    }

    let temp_dir_str = temp_dir.path().to_string_lossy();
    let destination_path = format!(
        "{}/{}",
        temp_dir_str,
        cmx_path
            .file_name()
            .ok_or(format_err!("file_name failed on {:#?}", cmx_path))?
            .to_string_lossy()
    );

    let cmc = cmc_path(fuchsia_config)?;

    let output = Command::new(cmc)
        .arg("format")
        .arg(cmx_path)
        .arg("-o")
        .arg(&destination_path)
        .output()
        .context("Running `cmc` to format cmx file")?;

    if !output.status.success() {
        bail!("cmc returned error: {}", String::from_utf8_lossy(&output.stderr));
    }

    Ok(PathBuf::from(destination_path))
}

fn write_manifest_file(
    verbose: bool,
    target_options: &TargetOptions<'_, '_>,
    run_cargo_options: &RunCargoOptions,
    target: &Path,
    binary_path: &Path,
    package_path: &Path,
    cmx_or_cml_path: &Path,
    package_name: &str,
    app_dir: &str,
    app_name: &str,
) -> Result<(), Error> {
    if verbose {
        println!("write_manifest_file: target = {:#?}", target);
    }
    let mut manifest = File::create(&target)?;
    let target_out_path = target_out_dir(target_options.config)?;
    let target_out_path_str = target_out_path.to_string_lossy();
    let shared_lib_path = shared_libraries_path(target_options)?;
    let shared_lib_str = shared_lib_path.to_string_lossy();
    let libc_path = format!("{}/libc.so", get_user_libc_path(target_options)?.to_string_lossy());
    let fdio_path = format!("{}/libfdio.so", shared_lib_str);
    let libsyslog_path = format!("{}/libsyslog.so", shared_lib_str);
    let libtraceengine_path = format!("{}/libtrace-engine.so", shared_lib_str);
    let libasync_path = format!("{}/libasync-default.so", shared_lib_str);
    let libcpp2_path =
        format!("{}/obj/build/images/fuchsia.zbi/bootfs/lib/libc++.so.2", target_out_path_str,);
    let libcpp1abi_path =
        format!("{}/obj/build/images/fuchsia.zbi/bootfs/lib/libc++abi.so.1", target_out_path_str,);
    let libunwind_path =
        format!("{}/obj/build/images/fuchsia.zbi/bootfs/lib/libunwind.so.1", target_out_path_str,);

    let additional_libs: Vec<String> = run_cargo_options
        .fargo_manifest
        .additional_shared_libraries
        .iter()
        .map(|lib_name| {
            format!("lib/{}={}/{}", lib_name, shared_lib_path.to_string_lossy(), lib_name)
        })
        .collect();

    let additional_lib_str = additional_libs.join("\n");

    let target_crate_path = target_crate_path(&run_cargo_options.manifest_path)?;
    let target_crate_path_string = target_crate_path.to_string_lossy();

    let data_files: Vec<String> = run_cargo_options
        .fargo_manifest
        .data_files
        .iter()
        .map(|data_file| {
            format!("{}={}/{}", data_file.dst, target_crate_path_string, data_file.src)
        })
        .collect();

    let data_files_str = data_files.join("\n");

    writeln!(
        manifest,
        r#"{}/{}={}
lib/ld.so.1={}
lib/libfdio.so={}
lib/libsyslog.so={}
lib/libtrace-engine.so={}
lib/libasync-default.so={}
lib/libc++.so.2={}
lib/libc++abi.so.1={}
lib/libunwind.so.1={}
meta/package={}
meta/{}.{}={}
{}
{}
"#,
        app_dir,
        app_name,
        binary_path.to_string_lossy(),
        libc_path,
        fdio_path,
        libsyslog_path,
        libtraceengine_path,
        libasync_path,
        libcpp2_path,
        libcpp1abi_path,
        libunwind_path,
        package_path.to_string_lossy(),
        package_name,
        cmx_or_cml_path.extension().expect("Failed to get manifest extension").to_string_lossy(),
        cmx_or_cml_path.to_string_lossy(),
        additional_lib_str,
        data_files_str,
    )?;
    Ok(())
}

fn write_package_file(verbose: bool, target: &Path, package_name: &str) -> Result<(), Error> {
    let mut package = File::create(&target)?;
    let package_contents = json!({
        "name": package_name,
        "version": "0"
    });
    if verbose {
        println!("write_package_file: target = {:#?}", target);
        println!("write_package_file: package_contents = {:#?}", package_contents);
    }
    writeln!(package, "{}", package_contents.to_string())?;
    Ok(())
}

fn pm_build(
    verbose: bool,
    target_options: &TargetOptions<'_, '_>,
    manifest_path: &Path,
    output_path: &Path,
) -> Result<(), Error> {
    let pm = package_manager_path(target_options.config)?;

    let fuchsia_dir = fuchsia_dir()?;
    let dev_key_path = fuchsia_dir.join("build/development.key");
    if verbose {
        println!("pm_build: package_manager_path = {:#?}", pm);
        println!("pm_build: fuchsia_dir = {:#?}", fuchsia_dir);
        println!("pm_build: dev_key_path = {:#?}", dev_key_path);
        println!("pm_build: manifest_path = {:#?}", manifest_path);
        println!("pm_build: output_path = {:#?}", output_path);
    }
    let output = Command::new(pm)
        .arg("-k")
        .arg(dev_key_path)
        .arg("-o")
        .arg(&output_path)
        .arg("-m")
        .arg(&manifest_path)
        .arg("build")
        .arg("-depfile")
        .arg("-blobsfile")
        .arg("-blobs-manifest")
        .output()
        .context("Running `cmc` to format cmx file")?;

    if verbose {
        println!("pm build stdout: {}", String::from_utf8_lossy(&output.stdout));
        if output.status.success() {
            println!("pm build stderr: {}", String::from_utf8_lossy(&output.stderr));
        }
    }

    if !output.status.success() {
        bail!("pm returned error: {}", String::from_utf8_lossy(&output.stderr));
    }

    Ok(())
}

fn pm_archive(
    verbose: bool,
    target_options: &TargetOptions<'_, '_>,
    output_path: &Path,
    manifest_path: &Path,
) -> Result<(), Error> {
    if verbose {
        println!("pm_archive: output_path = {:#?}", output_path);
        println!("pm_archive: manifest_path = {:#?}", manifest_path);
    }
    let pm = package_manager_path(target_options.config)?;

    let output = Command::new(pm)
        .arg("-o")
        .arg(&output_path)
        .arg("-m")
        .arg(&manifest_path)
        .arg("archive")
        .output()
        .context("Running `pm_archive` to build an archive")?;

    if verbose {
        println!("pm archive stdout: {}", String::from_utf8_lossy(&output.stdout));
        if output.status.success() {
            println!("pm archive stderr: {}", String::from_utf8_lossy(&output.stderr));
        }
    }

    if !output.status.success() {
        bail!("pm returned error: {}", String::from_utf8_lossy(&output.stderr));
    }

    Ok(())
}

fn pm_publish(
    verbose: bool,
    target_options: &TargetOptions<'_, '_>,
    output_path: &Path,
) -> Result<(), Error> {
    let pm = package_manager_path(target_options.config)?;
    let tuf_root = amber_path(target_options.config)?;
    if verbose {
        println!("pm_publish: output_path = {:#?}", output_path);
        println!("pm_publish: tuf_root = {:#?}", tuf_root);
    }
    let output = Command::new(pm)
        .arg("publish")
        .arg("-a")
        .arg("-f")
        .arg(output_path)
        .arg("-r")
        .arg(tuf_root)
        .arg("-vt")
        .arg("-v")
        .output()
        .context("Running `publish` to publish package")?;

    if verbose {
        println!("pm publish stdout: {}", String::from_utf8_lossy(&output.stdout));
        if output.status.success() {
            println!("pm publish stderr: {}", String::from_utf8_lossy(&output.stderr));
        }
    }

    if !output.status.success() {
        bail!("pm returned error: {}", String::from_utf8_lossy(&output.stderr));
    }

    Ok(())
}

pub fn make_package(
    verbose: bool,
    target_options: &TargetOptions<'_, '_>,
    run_cargo_options: &RunCargoOptions,
    binary_path: &Path,
    app_dir: &str,
    app_name: &str,
) -> Result<String, Error> {
    let temp_dir = tempdir()?;

    let binary_parent =
        binary_path.parent().expect(&format!("Can't get parent of {:#?}", binary_path));
    let mut package_name = binary_path
        .file_name()
        .expect("file_name failed on binary_path")
        .to_string_lossy()
        .to_string();
    package_name.push_str("_fargo");
    if verbose {
        println!("make_package: package_name = {:#?}", package_name);
    }
    let output_path = binary_parent.join(&package_name);
    if verbose {
        println!("make_package: output_path = {:#?}", output_path);
    }
    create_dir_all(&output_path).context("create_dir_all failed")?;
    let stripped_binary_path = strip_binary(binary_path)?;

    let dfs;
    let sandbox_file_path = match run_cargo_options.sandbox_file_path.as_ref() {
        Some(sandbox_file_path) => sandbox_file_path,
        None => {
            dfs = default_sandbox_file(&temp_dir)?;
            &dfs
        }
    };

    let formatted_path = if is_v2_sandbox_file(sandbox_file_path)? {
        let included_cml_file = include_cmx_or_cml_file(
            verbose,
            &target_options.config,
            &sandbox_file_path,
            &temp_dir,
        )?;
        compile_cml_file(verbose, &target_options.config, &included_cml_file, &temp_dir)?
    } else {
        let included_cmx_file = include_cmx_or_cml_file(
            verbose,
            &target_options.config,
            &sandbox_file_path,
            &temp_dir,
        )?;
        validate_cmx_file(verbose, &target_options.config, &included_cmx_file)?;
        format_cmx_file(verbose, &target_options.config, &included_cmx_file, &temp_dir)?
    };

    let package_path = temp_dir.path().join("package");
    write_package_file(verbose, &package_path, &package_name)?;
    let manifest_path = temp_dir.path().join("manifest");
    write_manifest_file(
        verbose,
        &target_options,
        &run_cargo_options,
        &manifest_path,
        &stripped_binary_path,
        &package_path,
        &formatted_path,
        &package_name,
        app_dir,
        app_name,
    )?;
    pm_build(verbose, &target_options, &manifest_path, &output_path).context("pm_build failed")?;
    pm_archive(verbose, &target_options, &output_path, &manifest_path)
        .context("pm_archive failed")?;
    pm_publish(verbose, &target_options, &output_path.join(format!("{}-0.far", package_name)))
        .context("pm_publish failed")?;
    Ok(format!(
        "fuchsia-pkg://fuchsia.com/{}#meta/{}.{}",
        package_name,
        package_name,
        formatted_path.extension().expect("Failed to get sandbox file extension").to_string_lossy()
    ))
}
