// 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_target_triple,
    sdk::{
        amber_path, clang_resource_dir, cmc_path, fuchsia_dir, package_manager_path,
        zircon_build_path, FuchsiaConfig, TargetOptions,
    },
    utils::strip_binary,
};
use failure::{bail, format_err, Error, ResultExt};
use serde_json::json;
use std::{
    fs::{create_dir_all, File},
    io::Write,
    path::{Path, PathBuf},
    process::Command,
};

fn validate_cmx_file(fuchsia_config: &FuchsiaConfig, cmx_path: &Path) -> Result<(), Error> {
    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 format_cmx_file(fuchsia_config: &FuchsiaConfig, cmx_path: &Path) -> Result<PathBuf, Error> {
    let destination_path = format!(
        "/tmp/{}",
        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(
    target_options: &TargetOptions<'_, '_>,
    target: &Path,
    binary_path: &Path,
    package_path: &Path,
    cmx_path: &Path,
    package_name: &str,
    app_name: &str,
) -> Result<(), Error> {
    let mut manifest = File::create(&target)?;
    let zircon_build = zircon_build_path(&target_options.config)?;
    let libc_path = format!(
        "{}/user-{}-gcc.shlib/obj/system/ulib/c/libc.so",
        zircon_build.to_string_lossy(),
        target_options.config.fuchsia_arch
    );
    let fdio_path = format!(
        "{}/user-{}-gcc.shlib/obj/system/ulib/fdio/libfdio.so",
        zircon_build.to_string_lossy(),
        target_options.config.fuchsia_arch
    );
    let target_triple = get_target_triple(target_options);
    let clang_resource_lib = clang_resource_dir(&target_triple)?.join(&target_triple).join("lib");
    let libsyslog_path = format!(
        "{}/user-{}-gcc.shlib/obj/system/ulib/syslog/libsyslog.so",
        zircon_build.to_string_lossy(),
        target_options.config.fuchsia_arch
    );
    writeln!(
        manifest,
        r#"bin/{}={}
lib/ld.so.1={}
lib/libfdio.so={}
lib/libunwind.so.1={}/libunwind.so.1
lib/libsyslog.so={}
meta/package={}
meta/{}.cmx={}
"#,
        app_name,
        binary_path.to_string_lossy(),
        libc_path,
        fdio_path,
        clang_resource_lib.to_string_lossy(),
        libsyslog_path,
        package_path.to_string_lossy(),
        package_name,
        cmx_path.to_string_lossy(),
    )?;
    Ok(())
}

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

fn pm_build(
    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");
    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 !output.status.success() {
        bail!("pm returned error: {}", String::from_utf8_lossy(&output.stderr));
    }

    Ok(())
}

fn pm_archive(
    target_options: &TargetOptions<'_, '_>,
    output_path: &Path,
    manifest_path: &Path,
) -> Result<(), Error> {
    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 `cmc` to format cmx file")?;

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

    Ok(())
}

fn pm_publish(target_options: &TargetOptions<'_, '_>, output_path: &Path) -> Result<(), Error> {
    let pm = package_manager_path(target_options.config)?;
    let tuf_root = amber_path(target_options.config)?;
    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 `cmc` to format cmx file")?;

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

    Ok(())
}

pub fn make_package(
    target_options: &TargetOptions<'_, '_>,
    binary_path: &Path,
    cmx_path: &Path,
    app_name: &str,
) -> Result<String, Error> {
    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");
    let output_path = binary_parent.join(&package_name);
    create_dir_all(&output_path).context("create_dir_all failed")?;
    let stripped_binary_path = strip_binary(binary_path)?;
    validate_cmx_file(&target_options.config, cmx_path)?;
    let formatted_path = format_cmx_file(&target_options.config, cmx_path)?;
    let package_path = PathBuf::from("/tmp/package");
    write_package_file(&package_path, &package_name)?;
    let manifest_path = PathBuf::from("/tmp/manifest");
    write_manifest_file(
        &target_options,
        &manifest_path,
        &stripped_binary_path,
        &package_path,
        &formatted_path,
        &package_name,
        app_name,
    )?;
    pm_build(&target_options, &manifest_path, &output_path).context("pm_build failed")?;
    pm_archive(&target_options, &output_path, &manifest_path).context("pm_archive failed")?;
    pm_publish(&target_options, &output_path.join(format!("{}-0.far", package_name)))
        .context("pm_publish failed")?;
    Ok(format!("fuchsia-pkg://fuchsia.com/{}#meta/{}.cmx", package_name, package_name))
}
