// Copyright 2021 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 anyhow::{anyhow, Context, Error, Result};
use assembly_config_schema::BoardDriverArguments;
use assembly_tool::Tool;
use assembly_util::BootfsDestination;
use camino::{Utf8Path, Utf8PathBuf};
use std::collections::BTreeMap;
use std::fs::File;
use std::io::Write;
use tracing::debug;
use zerocopy::AsBytes;

use crate::zbi_items::{ZbiBoardInfo, ZbiPlatformId};

/// Builder for the Zircon Boot Image (ZBI), which takes in a kernel, BootFS, boot args, and kernel
/// command line.
pub struct ZbiBuilder {
    /// The zbi host tool.
    tool: Box<dyn Tool>,

    kernel: Option<Utf8PathBuf>,
    // Map from file destination in the ZBI to the path of the source file on the host.
    bootfs_files: BTreeMap<String, Utf8PathBuf>,
    bootargs: Vec<String>,
    cmdline: Vec<String>,
    board_driver_arguments: Option<BoardDriverArguments>,

    // A ramdisk to add to the ZBI.
    ramdisk: Option<Utf8PathBuf>,

    // A devicetree binary to add to the ZBI
    devicetree: Option<Utf8PathBuf>,

    /// optional compression to use.
    compression: Option<String>,

    /// optional output manifest file
    output_manifest: Option<Utf8PathBuf>,
}

impl ZbiBuilder {
    /// Construct a new ZbiBuilder that uses the zbi |tool|.
    pub fn new(tool: Box<dyn Tool>) -> Self {
        Self {
            tool,
            kernel: None,
            bootfs_files: BTreeMap::default(),
            bootargs: Vec::default(),
            cmdline: Vec::default(),
            board_driver_arguments: None,
            ramdisk: None,
            devicetree: None,
            compression: None,
            output_manifest: None,
        }
    }

    /// Set the kernel to be used.
    pub fn set_kernel(&mut self, kernel: impl Into<Utf8PathBuf>) {
        self.kernel = Some(kernel.into());
    }

    /// Add a file to the bootfs as a merkle root identified blob.
    pub fn add_bootfs_blob(
        &mut self,
        source: impl Into<Utf8PathBuf>,
        merkle_root: impl std::fmt::Display,
    ) {
        // Every file that is part of a package included in the bootfs image
        // will exist under a `blob` directory, and will be identified by
        // its merkle root.
        let bootfs_path = format!("blob/{}", merkle_root);
        self.bootfs_files.insert(bootfs_path.to_string(), source.into());
    }

    /// Add a BootFS file to the ZBI.
    pub fn add_bootfs_file(
        &mut self,
        source: impl Into<Utf8PathBuf>,
        destination: impl AsRef<str>,
    ) {
        if self.bootfs_files.contains_key(destination.as_ref()) {
            println!("Found duplicate bootfs destination: {}", destination.as_ref());
            return;
        }
        self.bootfs_files.insert(destination.as_ref().to_string(), source.into());
    }

    /// Add a boot argument to the ZBI.
    pub fn add_boot_arg(&mut self, arg: &str) {
        self.bootargs.push(arg.to_string());
    }

    /// Add a kernel command line argument.
    pub fn add_cmdline_arg(&mut self, arg: &str) {
        self.cmdline.push(arg.to_string());
    }

    /// Add optional board driver arguments to be added as ZBI items.
    pub fn set_board_driver_arguments(&mut self, args: BoardDriverArguments) {
        self.board_driver_arguments = Some(args);
    }

    /// Add a ramdisk to the ZBI.
    pub fn add_ramdisk(&mut self, source: impl Into<Utf8PathBuf>) {
        self.ramdisk = Some(source.into());
    }

    /// Add a devicetree binary to the ZBI.
    pub fn add_devicetree(&mut self, source: impl Into<Utf8PathBuf>) {
        self.devicetree = Some(source.into());
    }

    /// Set the compression to use with the ZBI.
    pub fn set_compression(&mut self, compress: impl ToString) {
        self.compression = Some(compress.to_string());
    }

    /// Set the path to an optional JSON output manifest to produce.
    pub fn set_output_manifest(&mut self, manifest: impl Into<Utf8PathBuf>) {
        self.output_manifest = Some(manifest.into());
    }

    /// Build the ZBI.
    pub fn build(self, gendir: impl AsRef<Utf8Path>, output: impl AsRef<Utf8Path>) -> Result<()> {
        // Create the additional_boot_args.
        // TODO(https://fxbug.dev/42157396): Switch to the boot args file once we are no longer
        // comparing to the GN build.
        let additional_boot_args_path = gendir.as_ref().join("additional_boot_args.txt");
        let mut additional_boot_args = File::create(&additional_boot_args_path)
            .map_err(|e| Error::new(e).context("failed to create the additional boot args"))?;
        self.write_boot_args(&mut additional_boot_args)?;

        let (platform_id_path, board_info_path) =
            if let Some(BoardDriverArguments { vendor_id, product_id, revision, ref name }) =
                self.board_driver_arguments
            {
                let platform_id = ZbiPlatformId::new(vendor_id, product_id, name)?;
                let board_info = ZbiBoardInfo { revision };

                let platform_id_path = gendir.as_ref().join("platform_id.bin");
                let board_info_path = gendir.as_ref().join("board_info.bin");

                std::fs::write(&platform_id_path, platform_id.as_bytes())
                    .with_context(|| format!("writing platform_id to: {}", platform_id_path))?;

                std::fs::write(&board_info_path, board_info.as_bytes())
                    .with_context(|| format!("writing board_info to: {}", platform_id_path))?;

                (Some(platform_id_path), Some(board_info_path))
            } else {
                (None, None)
            };

        // Create the BootFS manifest file that lists all the files to insert
        // into BootFS.
        let bootfs_manifest_path = gendir.as_ref().join("bootfs_files.list");
        let mut bootfs_manifest = File::create(&bootfs_manifest_path)
            .map_err(|e| Error::new(e).context("failed to create the bootfs manifest"))?;
        self.write_bootfs_manifest(additional_boot_args_path, &mut bootfs_manifest)?;

        // Run the zbi tool to construct the ZBI.
        let zbi_args = self.build_zbi_args(
            &bootfs_manifest_path,
            None::<Utf8PathBuf>,
            platform_id_path,
            board_info_path,
            output,
        )?;
        debug!("ZBI command args: {:?}", zbi_args);

        self.tool.run(&zbi_args)
    }

    fn write_bootfs_manifest(
        &self,
        additional_boot_args_path: impl Into<Utf8PathBuf>,
        out: &mut impl Write,
    ) -> Result<()> {
        let mut bootfs_files = self.bootfs_files.clone();
        bootfs_files.insert(
            BootfsDestination::AdditionalBootArgs.to_string(),
            additional_boot_args_path.into(),
        );
        for (destination, source) in bootfs_files {
            write!(out, "{}", destination)?;
            write!(out, "=")?;
            // TODO(fxbug.dev76135): Use the zbi tool's set of valid inputs instead of constraining
            // to valid UTF-8.
            writeln!(out, "{}", source)?;
        }
        Ok(())
    }

    fn write_boot_args(&self, out: &mut impl Write) -> Result<()> {
        for arg in &self.bootargs {
            writeln!(out, "{}", arg)?;
        }
        Ok(())
    }

    fn build_zbi_args(
        &self,
        bootfs_manifest_path: impl AsRef<Utf8Path>,
        boot_args_path: Option<impl AsRef<Utf8Path>>,
        platform_id_path: Option<impl AsRef<Utf8Path>>,
        board_info_path: Option<impl AsRef<Utf8Path>>,
        output_path: impl AsRef<Utf8Path>,
    ) -> Result<Vec<String>> {
        // Ensure a kernel is supplied.
        let kernel = &self.kernel.as_ref().ok_or(anyhow!("No kernel image supplied"))?;

        let mut args: Vec<String> = Vec::new();

        // Add the kernel itself, first, to make a bootable ZBI.
        args.push("--type=container".to_string());
        args.push(kernel.to_string());

        // Then, add the kernel cmdline args.
        args.push("--type=cmdline".to_string());
        for cmd in &self.cmdline {
            args.push(format!("--entry={}", cmd));
        }

        if let Some(platform_id_path) = platform_id_path {
            args.push("--type=platform_id".to_string());
            args.push(platform_id_path.as_ref().to_string());
        }

        if let Some(board_info_path) = board_info_path {
            args.push("--type=drv_board_info".to_string());
            args.push(board_info_path.as_ref().to_string());
        }

        if let Some(devicetree_path) = &self.devicetree {
            args.push("--type=devicetree".to_string());
            args.push(devicetree_path.to_string());
        }

        // Then, add the bootfs files.
        args.push("--files".to_string());
        args.push(bootfs_manifest_path.as_ref().to_string());

        // Instead of supplying the additional_boot_args.txt file, we could use boot args. This is disabled
        // by default, in order to allow for binary diffing the ZBI to the in-tree built ZBI.
        if let Some(boot_args_path) = boot_args_path {
            let boot_args_path = boot_args_path.as_ref().to_string();
            args.push("--type=image_args".to_string());
            args.push(format!("--entry={}", boot_args_path));
        }

        // Add the ramdisk if needed.
        if let Some(ramdisk) = &self.ramdisk {
            args.push("--type=ramdisk".to_string());
            if let Some(compression) = &self.compression {
                args.push(format!("--compress={}", compression));
            }
            args.push(ramdisk.to_string());
        }

        // Set the compression level for bootfs files.
        if let Some(compression) = &self.compression {
            args.push(format!("--compressed={}", compression));
        }

        // Set the output file to write.
        args.push("--output".into());
        args.push(output_path.as_ref().to_string());

        // Create an output manifest that describes the contents of the built ZBI.
        if let Some(output_manifest) = &self.output_manifest {
            args.push("--json-output".into());
            args.push(output_manifest.to_string());
        }
        Ok(args)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    use assembly_tool::testing::FakeToolProvider;
    use assembly_tool::ToolProvider;

    #[test]
    fn bootfs_manifest_additional_boot_args_only() {
        let tools = FakeToolProvider::default();
        let zbi_tool = tools.get_tool("zbi").unwrap();
        let mut builder = ZbiBuilder::new(zbi_tool);
        let mut output: Vec<u8> = Vec::new();

        builder.write_bootfs_manifest("additional_boot_args.txt", &mut output).unwrap();
        let output_str = String::from_utf8(output).unwrap();
        assert_eq!(
            output_str,
            "config/additional_boot_args=additional_boot_args.txt\n".to_string()
        );

        let mut output: Vec<u8> = Vec::new();
        builder.add_bootfs_file("path/to/file2", "bin/file2");
        builder.add_bootfs_file("path/to/file1", "lib/file1");
        builder.write_bootfs_manifest("additional_boot_args.txt", &mut output).unwrap();
        let output_str = String::from_utf8(output).unwrap();
        assert_eq!(
            output_str,
            "bin/file2=path/to/file2\nconfig/additional_boot_args=additional_boot_args.txt\nlib/file1=path/to/file1\n"
                .to_string()
        );
    }

    #[test]
    fn bootfs_manifest() {
        let tools = FakeToolProvider::default();
        let zbi_tool = tools.get_tool("zbi").unwrap();
        let mut builder = ZbiBuilder::new(zbi_tool);
        let mut output: Vec<u8> = Vec::new();

        builder.add_bootfs_file("path/to/file2", "bin/file2");
        builder.add_bootfs_file("path/to/file1", "lib/file1");
        builder.add_bootfs_blob("path/to/file1", "my_merkle");
        builder.write_bootfs_manifest("additional_boot_args.txt", &mut output).unwrap();
        assert_eq!(
            output,
            b"bin/file2=path/to/file2\nblob/my_merkle=path/to/file1\nconfig/additional_boot_args=additional_boot_args.txt\nlib/file1=path/to/file1\n"
        );
    }

    #[test]
    fn boot_args() {
        let tools = FakeToolProvider::default();
        let zbi_tool = tools.get_tool("zbi").unwrap();
        let mut builder = ZbiBuilder::new(zbi_tool);
        let mut output: Vec<u8> = Vec::new();

        builder.write_boot_args(&mut output).unwrap();
        assert_eq!(output, b"");

        output.clear();
        builder.add_boot_arg("boot-arg1");
        builder.add_boot_arg("boot-arg2");
        builder.write_boot_args(&mut output).unwrap();
        assert_eq!(output, b"boot-arg1\nboot-arg2\n");
    }

    #[test]
    fn zbi_args_missing_kernel() {
        let tools = FakeToolProvider::default();
        let zbi_tool = tools.get_tool("zbi").unwrap();
        let builder = ZbiBuilder::new(zbi_tool);
        assert!(builder
            .build_zbi_args("bootfs", Some("bootargs"), None::<String>, None::<String>, "output")
            .is_err());
    }

    #[test]
    fn zbi_args_with_kernel() {
        let tools = FakeToolProvider::default();
        let zbi_tool = tools.get_tool("zbi").unwrap();
        let mut builder = ZbiBuilder::new(zbi_tool);
        builder.set_kernel("path/to/kernel");
        let args = builder
            .build_zbi_args("bootfs", Some("bootargs"), None::<String>, None::<String>, "output")
            .unwrap();
        assert_eq!(
            args,
            [
                "--type=container",
                "path/to/kernel",
                "--type=cmdline",
                "--files",
                "bootfs",
                "--type=image_args",
                "--entry=bootargs",
                "--output",
                "output",
            ]
        );
    }

    #[test]
    fn zbi_args_with_kernel_with_devicetree() {
        let tools = FakeToolProvider::default();
        let zbi_tool = tools.get_tool("zbi").unwrap();
        let mut builder = ZbiBuilder::new(zbi_tool);
        builder.set_kernel("path/to/kernel");
        builder.add_devicetree("path/to/devicetree");
        let args = builder
            .build_zbi_args("bootfs", Some("bootargs"), None::<String>, None::<String>, "output")
            .unwrap();
        assert_eq!(
            args,
            [
                "--type=container",
                "path/to/kernel",
                "--type=cmdline",
                "--type=devicetree",
                "path/to/devicetree",
                "--files",
                "bootfs",
                "--type=image_args",
                "--entry=bootargs",
                "--output",
                "output",
            ]
        );
    }

    #[test]
    fn zbi_args_with_cmdline() {
        let tools = FakeToolProvider::default();
        let zbi_tool = tools.get_tool("zbi").unwrap();
        let mut builder = ZbiBuilder::new(zbi_tool);
        builder.set_kernel("path/to/kernel");
        builder.add_cmdline_arg("cmd-arg1");
        builder.add_cmdline_arg("cmd-arg2");
        let args = builder
            .build_zbi_args("bootfs", Some("bootargs"), None::<String>, None::<String>, "output")
            .unwrap();
        assert_eq!(
            args,
            [
                "--type=container",
                "path/to/kernel",
                "--type=cmdline",
                "--entry=cmd-arg1",
                "--entry=cmd-arg2",
                "--files",
                "bootfs",
                "--type=image_args",
                "--entry=bootargs",
                "--output",
                "output",
            ]
        );
    }

    #[test]
    fn zbi_args_without_boot_args() {
        let tools = FakeToolProvider::default();
        let zbi_tool = tools.get_tool("zbi").unwrap();
        let mut builder = ZbiBuilder::new(zbi_tool);
        builder.set_kernel("path/to/kernel");
        builder.add_cmdline_arg("cmd-arg1");
        builder.add_cmdline_arg("cmd-arg2");
        let args = builder
            .build_zbi_args("bootfs", None::<String>, None::<String>, None::<String>, "output")
            .unwrap();
        assert_eq!(
            args,
            [
                "--type=container",
                "path/to/kernel",
                "--type=cmdline",
                "--entry=cmd-arg1",
                "--entry=cmd-arg2",
                "--files",
                "bootfs",
                "--output",
                "output",
            ]
        );
    }

    #[test]
    fn zbi_args_with_compression() {
        let tools = FakeToolProvider::default();
        let zbi_tool = tools.get_tool("zbi").unwrap();
        let mut builder = ZbiBuilder::new(zbi_tool);
        builder.set_kernel("path/to/kernel");
        builder.add_cmdline_arg("cmd-arg1");
        builder.add_cmdline_arg("cmd-arg2");
        builder.set_compression("zstd.max");
        let args = builder
            .build_zbi_args("bootfs", None::<String>, None::<String>, None::<String>, "output")
            .unwrap();
        assert_eq!(
            args,
            [
                "--type=container",
                "path/to/kernel",
                "--type=cmdline",
                "--entry=cmd-arg1",
                "--entry=cmd-arg2",
                "--files",
                "bootfs",
                "--compressed=zstd.max",
                "--output",
                "output",
            ]
        );
    }

    #[test]
    fn zbi_args_with_manifest() {
        let tools = FakeToolProvider::default();
        let zbi_tool = tools.get_tool("zbi").unwrap();
        let mut builder = ZbiBuilder::new(zbi_tool);
        builder.set_kernel("path/to/kernel");
        builder.add_cmdline_arg("cmd-arg1");
        builder.add_cmdline_arg("cmd-arg2");
        builder.set_output_manifest("path/to/manifest");
        let args = builder
            .build_zbi_args("bootfs", None::<String>, None::<String>, None::<String>, "output")
            .unwrap();
        assert_eq!(
            args,
            [
                "--type=container",
                "path/to/kernel",
                "--type=cmdline",
                "--entry=cmd-arg1",
                "--entry=cmd-arg2",
                "--files",
                "bootfs",
                "--output",
                "output",
                "--json-output",
                "path/to/manifest",
            ]
        );
    }

    #[test]
    fn zbi_args_with_board_driver_args() {
        let tools = FakeToolProvider::default();
        let zbi_tool = tools.get_tool("zbi").unwrap();
        let mut builder = ZbiBuilder::new(zbi_tool);
        builder.set_kernel("path/to/kernel");
        builder.set_output_manifest("path/to/manifest");
        let args = builder
            .build_zbi_args(
                "bootfs",
                None::<String>,
                Some("gen/platform_id_path"),
                Some("gen/board_info_path"),
                "output",
            )
            .unwrap();
        assert_eq!(
            args,
            [
                "--type=container",
                "path/to/kernel",
                "--type=cmdline",
                "--type=platform_id",
                "gen/platform_id_path",
                "--type=drv_board_info",
                "gen/board_info_path",
                "--files",
                "bootfs",
                "--output",
                "output",
                "--json-output",
                "path/to/manifest",
            ]
        );
    }
}
