// 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,
) -> 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/app={}
lib/ld.so.1={}
lib/libfdio.so={}
lib/libunwind.so.1={}/libunwind.so.1
lib/libsyslog.so={}
meta/package={}
meta/{}.cmx={}
"#,
        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,
) -> 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,
    )?;
    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))
}
