// 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::Result;
use assembly_tool::Tool;
use camino::Utf8PathBuf;

/// A builder that receives a sparse FVM, and prepares it for nand flashing.
///
/// ```
/// let builder = NandFvmBuilder {
///     output: Utf8PathBuf::from("path/to/output.blk"),
///     sparse_fvm: Utf8PathBuf::from("path/to/fvm.sparse.blk"),
///     max_disk_size: None,
///     compression: None,
///     page_size: 0,
///     oob_size: 0,
///     pages_per_block: 0,
///     block_count: 0,
/// };
/// builder.build();
/// ```

pub struct NandFvmBuilder {
    /// The fvm host tool.
    pub tool: Box<dyn Tool>,
    /// The path to write the FVM to.
    pub output: Utf8PathBuf,
    /// The path to the sparse FVM on the host.
    pub sparse_fvm: Utf8PathBuf,
    /// The maximum disk size for the sparse FVM.
    /// The build will fail if the sparse FVM is larger than this.
    pub max_disk_size: Option<u64>,
    /// The compression algorithm to use.
    pub compression: Option<String>,
    /// The nand page size.
    pub page_size: u64,
    /// The out of bound size.
    pub oob_size: u64,
    /// The pages per block.
    pub pages_per_block: u64,
    /// The number of blocks.
    pub block_count: u64,
}

impl NandFvmBuilder {
    /// Build the FVM.
    pub fn build(self) -> Result<()> {
        let args = self.build_args()?;
        self.tool.run(&args)
    }

    fn build_args(&self) -> Result<Vec<String>> {
        let mut args: Vec<String> = Vec::new();
        args.push(self.output.to_string());
        args.push("ftl-raw-nand".to_string());

        // Append key and value to the `args` if the value is present.
        fn maybe_append_value(
            args: &mut Vec<String>,
            key: impl AsRef<str>,
            value: Option<impl std::string::ToString>,
        ) {
            if let Some(value) = value {
                args.push(format!("--{}", key.as_ref()));
                args.push(value.to_string());
            }
        }

        maybe_append_value(&mut args, "nand-page-size", Some(self.page_size));
        maybe_append_value(&mut args, "nand-oob-size", Some(self.oob_size));
        maybe_append_value(&mut args, "nand-pages-per-block", Some(self.pages_per_block));
        maybe_append_value(&mut args, "nand-block-count", Some(self.block_count));
        maybe_append_value(&mut args, "max-disk-size", self.max_disk_size);
        maybe_append_value(&mut args, "compress", self.compression.as_ref());

        // A quirk of the FVM tool means the sparse argument *must* go last.
        maybe_append_value(&mut args, "sparse", Some(self.sparse_fvm.to_string()));

        Ok(args)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use assembly_tool::testing::FakeToolProvider;
    use assembly_tool::ToolProvider;

    #[test]
    fn nand_args() {
        let tools = FakeToolProvider::default();
        let fvm_tool = tools.get_tool("fvm").unwrap();
        let builder = NandFvmBuilder {
            tool: fvm_tool,
            output: "mypath".into(),
            sparse_fvm: "sparsepath".into(),
            max_disk_size: Some(500),
            compression: Some("supercompress".into()),
            page_size: 1,
            oob_size: 2,
            pages_per_block: 3,
            block_count: 4,
        };
        let args = builder.build_args().unwrap();
        assert_eq!(
            args,
            [
                "mypath",
                "ftl-raw-nand",
                "--nand-page-size",
                "1",
                "--nand-oob-size",
                "2",
                "--nand-pages-per-block",
                "3",
                "--nand-block-count",
                "4",
                "--max-disk-size",
                "500",
                "--compress",
                "supercompress",
                "--sparse",
                "sparsepath",
            ]
        );
    }
}
