// Copyright 2022 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::board_filesystem_config as bfc;
use crate::product_filesystem_config as pfc;
use anyhow::{anyhow, bail, Context, Result};
use bfc::{PostProcessingScript, VBMetaDescriptor, ZbiCompression};
use camino::Utf8PathBuf;
use pfc::BlobfsLayout;
use serde::{Deserialize, Serialize};

use std::fmt;
use std::io::Read;
use std::str::FromStr;

/// The configuration file specifying which images to generate and how.
#[derive(Serialize, Deserialize, Debug, Default, PartialEq)]
pub struct ImagesConfig {
    /// A list of images to generate.
    #[serde(default)]
    pub images: Vec<Image>,
}

/// An image to generate.
#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[serde(tag = "type")]
pub enum Image {
    /// A FVM image.
    #[serde(rename = "fvm")]
    Fvm(Fvm),

    /// A ZBI image.
    #[serde(rename = "zbi")]
    Zbi(Zbi),

    /// A VBMeta image.
    #[serde(rename = "vbmeta")]
    VBMeta(VBMeta),

    /// An Fxfs image.
    #[serde(rename = "fxfs")]
    Fxfs(Fxfs),
}

/// Parameters describing how to generate the ZBI.
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct Zbi {
    /// The name to give the image file.
    #[serde(default = "default_zbi_name")]
    pub name: String,

    /// The compression format for the ZBI.
    #[serde(default)]
    pub compression: ZbiCompression,

    /// An optional script to post-process the ZBI.
    /// This is often used to prepare the ZBI for flashing/updating.
    #[serde(default)]
    #[serde(skip_serializing_if = "Option::is_none")]
    pub postprocessing_script: Option<PostProcessingScript>,
}

fn default_zbi_name() -> String {
    "fuchsia".into()
}

impl FromStr for ZbiCompression {
    type Err = anyhow::Error;
    fn from_str(s: &str) -> Result<Self> {
        zbi_compression_from_str(s)
    }
}

impl TryFrom<&str> for ZbiCompression {
    type Error = anyhow::Error;
    fn try_from(s: &str) -> Result<Self> {
        zbi_compression_from_str(s)
    }
}

impl fmt::Display for ZbiCompression {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(
            f,
            "{}",
            match self {
                ZbiCompression::ZStd => "zstd",
                ZbiCompression::ZStdMax => "zstd.max",
            }
        )
    }
}

fn zbi_compression_from_str(s: &str) -> Result<ZbiCompression> {
    match s {
        "zstd" => Ok(ZbiCompression::ZStd),
        "zstd.max" => Ok(ZbiCompression::ZStdMax),
        invalid => Err(anyhow!("invalid zbi compression: {}", invalid)),
    }
}

/// The parameters describing how to create a VBMeta image.
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct VBMeta {
    /// The name to give the image file.
    #[serde(default = "default_vbmeta_name")]
    pub name: String,

    /// Path on host to the key for signing VBMeta.
    pub key: Utf8PathBuf,

    /// Path on host to the key metadata to add to the VBMeta.
    pub key_metadata: Utf8PathBuf,

    /// Optional descriptors to add to the VBMeta image.
    #[serde(default)]
    pub additional_descriptors: Vec<VBMetaDescriptor>,
}

fn default_vbmeta_name() -> String {
    "fuchsia".into()
}

/// The parameters describing how to create a FVM image.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct Fvm {
    /// The size of a slice within the FVM.
    #[serde(default = "default_fvm_slice_size")]
    pub slice_size: u64,

    /// The list of filesystems to generate that can be added to the outputs.
    pub filesystems: Vec<FvmFilesystem>,

    /// The FVM images to generate.
    pub outputs: Vec<FvmOutput>,
}

fn default_fvm_slice_size() -> u64 {
    8388608
}

/// A single FVM filesystem that can be added to multiple outputs.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(tag = "type")]
pub enum FvmFilesystem {
    /// A blobfs volume for holding blobs.
    #[serde(rename = "blobfs")]
    BlobFS(BlobFS),

    /// An empty data partition.
    /// This reserves the data volume, which will be formatted as fxfs/minfs on boot.
    // TODO(https://fxbug.dev/42166000): Remove empty-minfs alias after updating sdk-integration.
    #[serde(rename = "empty-data", alias = "empty-minfs")]
    EmptyData(EmptyData),

    /// Reserved slices in the FVM.
    #[serde(rename = "reserved")]
    Reserved(Reserved),
}

/// Configuration for building a BlobFS volume.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct BlobFS {
    /// The name of the volume in the FVM.
    #[serde(default = "default_blobfs_name")]
    pub name: String,

    /// Optional deprecated layout.
    #[serde(default)]
    pub layout: BlobfsLayout,

    /// Reserve |minimum_data_bytes| and |minimum_inodes| in the FVM, and ensure
    /// that the final reserved size does not exceed |maximum_bytes|.
    #[serde(default)]
    #[serde(skip_serializing_if = "Option::is_none")]
    pub maximum_bytes: Option<u64>,

    /// Reserve space for at least this many data bytes.
    #[serde(default)]
    #[serde(skip_serializing_if = "Option::is_none")]
    pub minimum_data_bytes: Option<u64>,

    /// Reserved space for this many inodes.
    #[serde(default)]
    #[serde(skip_serializing_if = "Option::is_none")]
    pub minimum_inodes: Option<u64>,

    /// Maximum amount of contents for an assembled blobfs.
    #[serde(default)]
    #[serde(skip_serializing_if = "Option::is_none")]
    pub maximum_contents_size: Option<u64>,
}

fn default_blobfs_name() -> String {
    "blob".into()
}

fn default_data_name() -> String {
    "data".into()
}

/// Configuration for building an EmptyData volume.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct EmptyData {
    /// The name of the volume in the FVM.
    #[serde(default = "default_data_name")]
    pub name: String,
}

/// Configuration for building a Reserved volume.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct Reserved {
    /// The name of the volume in the FVM.
    #[serde(default = "default_reserved_name")]
    pub name: String,

    /// The number of slices to reserve.
    pub slices: u64,
}

fn default_reserved_name() -> String {
    "internal".into()
}

impl FromStr for BlobfsLayout {
    type Err = anyhow::Error;
    fn from_str(s: &str) -> Result<Self> {
        blobfs_layout_from_str(s)
    }
}

impl TryFrom<&str> for BlobfsLayout {
    type Error = anyhow::Error;
    fn try_from(s: &str) -> Result<Self> {
        blobfs_layout_from_str(s)
    }
}

impl fmt::Display for BlobfsLayout {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(
            f,
            "{}",
            match self {
                BlobfsLayout::Compact => "compact",
                BlobfsLayout::DeprecatedPadded => "deprecated_padded",
            }
        )
    }
}

fn blobfs_layout_from_str(s: &str) -> Result<BlobfsLayout> {
    match s {
        "compact" => Ok(BlobfsLayout::Compact),
        "deprecated_padded" => Ok(BlobfsLayout::DeprecatedPadded),
        _ => Err(anyhow!("invalid blobfs layout")),
    }
}

/// A FVM image to generate with a list of filesystems.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(tag = "type")]
pub enum FvmOutput {
    /// The default FVM type with no modifications.
    #[serde(rename = "standard")]
    Standard(StandardFvm),

    /// A FVM that is compressed sparse.
    #[serde(rename = "sparse")]
    Sparse(SparseFvm),

    /// A FVM prepared for a Nand partition.
    #[serde(rename = "nand")]
    Nand(NandFvm),
}

impl std::fmt::Display for FvmOutput {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let (fvm_type, name) = match self {
            FvmOutput::Standard(fvm) => ("Standard", &fvm.name),
            FvmOutput::Sparse(fvm) => ("Sparse", &fvm.name),
            FvmOutput::Nand(fvm) => ("Nand", &fvm.name),
        };
        f.write_fmt(format_args!("Fvm::{}(\"{}\")", fvm_type, name))
    }
}

/// The default FVM type with no modifications.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct StandardFvm {
    /// The name to give the file.
    pub name: String,

    /// The filesystems to include in the FVM.
    pub filesystems: Vec<String>,

    /// Whether to compress the FVM.
    #[serde(default)]
    pub compress: bool,

    /// Shrink the FVM to fit exactly the contents.
    #[serde(default)]
    pub resize_image_file_to_fit: bool,

    /// After the optional resize, truncate the file to this length.
    #[serde(default)]
    #[serde(skip_serializing_if = "Option::is_none")]
    pub truncate_to_length: Option<u64>,
}

/// A FVM that is compressed sparse.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct SparseFvm {
    /// The name to give the file.
    pub name: String,

    /// The filesystems to include in the FVM.
    pub filesystems: Vec<String>,

    /// The maximum size the FVM can expand to at runtime.
    /// This sets the amount of slice metadata to allocate during construction,
    /// which cannot be modified at runtime.
    #[serde(default)]
    #[serde(skip_serializing_if = "Option::is_none")]
    pub max_disk_size: Option<u64>,
}

/// A FVM prepared for a Nand partition.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct NandFvm {
    /// The name to give the file.
    pub name: String,

    /// The filesystems to include in the FVM.
    #[serde(default)]
    pub filesystems: Vec<String>,

    /// The maximum size the FVM can expand to at runtime.
    /// This sets the amount of slice metadata to allocate during construction,
    /// which cannot be modified at runtime.
    #[serde(default)]
    #[serde(skip_serializing_if = "Option::is_none")]
    pub max_disk_size: Option<u64>,

    /// Whether to compress the FVM.
    #[serde(default)]
    pub compress: bool,

    /// The number of blocks.
    pub block_count: u64,

    /// The out of bound size.
    pub oob_size: u64,

    /// Page size as perceived by the FTL.
    pub page_size: u64,

    /// Number of pages per erase block unit.
    pub pages_per_block: u64,
}

/// The parameters describing how to create an Fxfs image.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct Fxfs {
    /// The size of Fxfs image to generate.  The base system's contents must not exceed this size.
    /// If unset, there's no limit, and the image will be an arbitrary size greater than or equal to
    /// the space needed for the base system's contents.
    #[serde(default)]
    #[serde(skip_serializing_if = "Option::is_none")]
    pub size_bytes: Option<u64>,

    /// Maximum amount of contents for an assembled Fxfs image.  Must be no greater than
    /// `size_bytes`.
    #[serde(default)]
    #[serde(skip_serializing_if = "Option::is_none")]
    pub maximum_contents_size: Option<u64>,
}

impl ImagesConfig {
    /// Parse the config from a reader.
    pub fn from_reader<R>(reader: &mut R) -> Result<Self>
    where
        R: Read,
    {
        let mut data = String::default();
        reader.read_to_string(&mut data).context("Cannot read the config")?;
        serde_json5::from_str(&data).context("Cannot parse the config")
    }

    /// Merge a product and board to construct an ImagesConfig.
    pub fn from_product_and_board(
        product: &pfc::ProductFilesystemConfig,
        board: &bfc::BoardFilesystemConfig,
    ) -> Result<Self> {
        let mut images = vec![];

        // Add the zbi and optional vbmeta specified in the board.
        images.push(Image::Zbi(Zbi {
            name: product.image_name.0.clone(),
            compression: board.zbi.compression.clone(),
            postprocessing_script: board.zbi.postprocessing_script.clone(),
        }));
        if let Some(vbmeta) = &board.vbmeta {
            let bfc::VBMeta { key, key_metadata, additional_descriptors } = vbmeta.clone();
            images.push(Image::VBMeta(VBMeta {
                name: product.image_name.0.clone(),
                key: key.into(),
                key_metadata: key_metadata.into(),
                additional_descriptors,
            }));
        }

        // Add the filesystems specified in the product.
        if product.image_mode != pfc::FilesystemImageMode::NoImage {
            match &product.volume {
                pfc::VolumeConfig::Fxfs => {
                    let size_bytes = board.fxfs.size_bytes;
                    images.push(Image::Fxfs(Fxfs {
                        size_bytes,
                        maximum_contents_size: board.fxfs.size_checker_maximum_bytes,
                    }));
                }
                pfc::VolumeConfig::Fvm(fvm) => {
                    let slice_size = board.fvm.slice_size.0;

                    // Construct the list of FVM filesystems.
                    let mut filesystems = vec![];
                    let mut filesystem_names = vec![];
                    if let Some(_) = fvm.data {
                        filesystems.push(FvmFilesystem::EmptyData(EmptyData {
                            name: "empty-data".into(),
                        }));
                        filesystem_names.push("empty-data".to_string());
                    }
                    if let Some(pfc::BlobFvmVolumeConfig { blob_layout }) = &fvm.blob {
                        filesystems.push(FvmFilesystem::BlobFS(BlobFS {
                            name: "blob".into(),
                            layout: blob_layout.clone(),
                            maximum_bytes: board.fvm.blobfs.build_time_maximum_bytes,
                            minimum_data_bytes: board.fvm.blobfs.minimum_data_bytes,
                            minimum_inodes: board.fvm.blobfs.minimum_inodes,
                            maximum_contents_size: board.fvm.blobfs.size_checker_maximum_bytes,
                        }));
                        filesystem_names.push("blob".to_string());
                    }
                    if let Some(pfc::ReservedFvmVolumeConfig { reserved_slices }) = fvm.reserved {
                        filesystems.push(FvmFilesystem::Reserved(Reserved {
                            name: "internal".into(),
                            slices: reserved_slices,
                        }));
                        filesystem_names.push("internal".to_string());
                    }
                    // Construct the list of FVM outputs.
                    let mut outputs = vec![];
                    outputs.push(FvmOutput::Standard(StandardFvm {
                        name: "fvm".into(),
                        filesystems: filesystem_names.clone(),
                        compress: false,
                        resize_image_file_to_fit: false,
                        truncate_to_length: board.fvm.truncate_to_length.clone(),
                    }));
                    if let Some(sparse) = &board.fvm.sparse_output {
                        outputs.push(FvmOutput::Sparse(SparseFvm {
                            name: "fvm.sparse".into(),
                            filesystems: filesystem_names.clone(),
                            max_disk_size: sparse.max_disk_size.clone(),
                        }));
                    }
                    if board.fvm.fastboot_output.is_some() && board.fvm.nand_output.is_some() {
                        bail!("A board may only build either a fastboot or nand FVM but not both");
                    }
                    if let Some(fastboot) = &board.fvm.fastboot_output {
                        outputs.push(FvmOutput::Standard(StandardFvm {
                            name: "fvm.fastboot".into(),
                            filesystems: filesystem_names.clone(),
                            compress: fastboot.compress,
                            resize_image_file_to_fit: true,
                            truncate_to_length: fastboot.truncate_to_length.clone(),
                        }));
                    } else if let Some(nand) = &board.fvm.nand_output {
                        let bfc::NandFvmConfig {
                            max_disk_size,
                            compress,
                            block_count,
                            oob_size,
                            page_size,
                            pages_per_block,
                        } = nand.clone();
                        outputs.push(FvmOutput::Nand(NandFvm {
                            name: "fvm.fastboot".into(),
                            filesystems: filesystem_names.clone(),
                            max_disk_size,
                            compress,
                            block_count,
                            oob_size,
                            page_size,
                            pages_per_block,
                        }));
                    }

                    // Add the FVM images.
                    images.push(Image::Fvm(Fvm { slice_size, filesystems, outputs }));
                }
            }
        }

        Ok(Self { images })
    }
}

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

    fn test_board_config_fastboot() -> bfc::BoardFilesystemConfig {
        bfc::BoardFilesystemConfig {
            zbi: bfc::Zbi {
                compression: bfc::ZbiCompression::ZStd,
                postprocessing_script: Some(bfc::PostProcessingScript {
                    path: "path/to/script".into(),
                    args: vec!["arg1".into(), "arg2".into()],
                }),
            },
            vbmeta: Some(bfc::VBMeta {
                key: "path/to/key".into(),
                key_metadata: "path/to/metadata".into(),
                additional_descriptors: vec![],
            }),
            fxfs: bfc::Fxfs { size_bytes: Some(1234), size_checker_maximum_bytes: Some(5678) },
            fvm: bfc::Fvm {
                slice_size: bfc::FvmSliceSize(5678),
                truncate_to_length: None,
                blobfs: bfc::Blobfs {
                    size_checker_maximum_bytes: Some(12),
                    build_time_maximum_bytes: Some(34),
                    maximum_bytes: None,
                    minimum_inodes: Some(56),
                    minimum_data_bytes: Some(78),
                },
                minfs: bfc::Minfs { maximum_bytes: Some(90) },
                sparse_output: Some(bfc::SparseFvmConfig { max_disk_size: Some(2345) }),
                nand_output: None,
                fastboot_output: Some(bfc::FastbootFvmConfig {
                    compress: true,
                    truncate_to_length: Some(3456),
                }),
            },
            gpt_all: false,
        }
    }

    fn test_board_config_nand() -> bfc::BoardFilesystemConfig {
        bfc::BoardFilesystemConfig {
            zbi: bfc::Zbi {
                compression: bfc::ZbiCompression::ZStd,
                postprocessing_script: Some(bfc::PostProcessingScript {
                    path: "path/to/script".into(),
                    args: vec!["arg1".into(), "arg2".into()],
                }),
            },
            vbmeta: Some(bfc::VBMeta {
                key: "path/to/key".into(),
                key_metadata: "path/to/metadata".into(),
                additional_descriptors: vec![],
            }),
            fxfs: bfc::Fxfs { size_bytes: Some(1234), size_checker_maximum_bytes: Some(5678) },
            fvm: bfc::Fvm {
                slice_size: bfc::FvmSliceSize(5678),
                truncate_to_length: None,
                blobfs: bfc::Blobfs {
                    size_checker_maximum_bytes: Some(12),
                    build_time_maximum_bytes: Some(34),
                    maximum_bytes: None,
                    minimum_inodes: Some(56),
                    minimum_data_bytes: Some(78),
                },
                minfs: bfc::Minfs { maximum_bytes: Some(90) },
                sparse_output: Some(bfc::SparseFvmConfig { max_disk_size: Some(2345) }),
                nand_output: Some(bfc::NandFvmConfig {
                    max_disk_size: Some(3456),
                    compress: true,
                    block_count: 1,
                    oob_size: 2,
                    page_size: 3,
                    pages_per_block: 4,
                }),
                fastboot_output: None,
            },
            gpt_all: false,
        }
    }

    #[test]
    fn from_product_and_board_no_images() {
        let board = test_board_config_fastboot();
        let product = pfc::ProductFilesystemConfig {
            image_name: pfc::ImageName("a-product".into()),
            watch_for_nand: false,
            format_data_on_corruption: pfc::FormatDataOnCorruption(true),
            no_zxcrypt: false,
            image_mode: pfc::FilesystemImageMode::NoImage,
            volume: pfc::VolumeConfig::Fxfs,
        };

        let images = ImagesConfig::from_product_and_board(&product, &board).unwrap();
        assert_eq!(
            images,
            ImagesConfig {
                images: vec![
                    Image::Zbi(Zbi {
                        name: "a-product".into(),
                        compression: bfc::ZbiCompression::ZStd,
                        postprocessing_script: Some(bfc::PostProcessingScript {
                            path: "path/to/script".into(),
                            args: vec!["arg1".into(), "arg2".into()],
                        }),
                    }),
                    Image::VBMeta(VBMeta {
                        name: "a-product".into(),
                        key: "path/to/key".into(),
                        key_metadata: "path/to/metadata".into(),
                        additional_descriptors: vec![],
                    }),
                ],
            }
        );
    }

    #[test]
    fn from_product_and_board_fxfs() {
        let board = test_board_config_fastboot();
        let product = pfc::ProductFilesystemConfig {
            image_name: pfc::ImageName("a-product".into()),
            watch_for_nand: false,
            format_data_on_corruption: pfc::FormatDataOnCorruption(true),
            no_zxcrypt: false,
            image_mode: pfc::FilesystemImageMode::Partition,
            volume: pfc::VolumeConfig::Fxfs,
        };

        let images = ImagesConfig::from_product_and_board(&product, &board).unwrap();
        assert_eq!(
            images,
            ImagesConfig {
                images: vec![
                    Image::Zbi(Zbi {
                        name: "a-product".into(),
                        compression: bfc::ZbiCompression::ZStd,
                        postprocessing_script: Some(bfc::PostProcessingScript {
                            path: "path/to/script".into(),
                            args: vec!["arg1".into(), "arg2".into()],
                        }),
                    }),
                    Image::VBMeta(VBMeta {
                        name: "a-product".into(),
                        key: "path/to/key".into(),
                        key_metadata: "path/to/metadata".into(),
                        additional_descriptors: vec![],
                    }),
                    Image::Fxfs(Fxfs { size_bytes: Some(1234), maximum_contents_size: Some(5678) }),
                ],
            }
        );
    }

    #[test]
    fn from_product_and_board_fvm_fastboot() {
        let board = test_board_config_fastboot();
        let product = pfc::ProductFilesystemConfig {
            image_name: pfc::ImageName("a-product".into()),
            watch_for_nand: false,
            format_data_on_corruption: pfc::FormatDataOnCorruption(true),
            no_zxcrypt: false,
            image_mode: pfc::FilesystemImageMode::Partition,
            volume: pfc::VolumeConfig::Fvm(pfc::FvmVolumeConfig {
                data: Some(pfc::DataFvmVolumeConfig {
                    use_disk_based_minfs_migration: true,
                    data_filesystem_format: pfc::DataFilesystemFormat::Minfs,
                }),
                blob: Some(pfc::BlobFvmVolumeConfig { blob_layout: BlobfsLayout::Compact }),
                reserved: Some(pfc::ReservedFvmVolumeConfig { reserved_slices: 7 }),
            }),
        };

        let images = ImagesConfig::from_product_and_board(&product, &board).unwrap();
        assert_eq!(
            images,
            ImagesConfig {
                images: vec![
                    Image::Zbi(Zbi {
                        name: "a-product".into(),
                        compression: bfc::ZbiCompression::ZStd,
                        postprocessing_script: Some(bfc::PostProcessingScript {
                            path: "path/to/script".into(),
                            args: vec!["arg1".into(), "arg2".into()],
                        }),
                    }),
                    Image::VBMeta(VBMeta {
                        name: "a-product".into(),
                        key: "path/to/key".into(),
                        key_metadata: "path/to/metadata".into(),
                        additional_descriptors: vec![],
                    }),
                    Image::Fvm(Fvm {
                        slice_size: 5678,
                        filesystems: vec![
                            FvmFilesystem::EmptyData(EmptyData { name: "empty-data".into() }),
                            FvmFilesystem::BlobFS(BlobFS {
                                name: "blob".into(),
                                layout: BlobfsLayout::Compact,
                                maximum_bytes: Some(34),
                                minimum_inodes: Some(56),
                                minimum_data_bytes: Some(78),
                                maximum_contents_size: Some(12),
                            }),
                            FvmFilesystem::Reserved(Reserved {
                                name: "internal".into(),
                                slices: 7,
                            }),
                        ],
                        outputs: vec![
                            FvmOutput::Standard(StandardFvm {
                                name: "fvm".into(),
                                filesystems: vec![
                                    "empty-data".to_string(),
                                    "blob".to_string(),
                                    "internal".to_string(),
                                ],
                                compress: false,
                                resize_image_file_to_fit: false,
                                truncate_to_length: None,
                            }),
                            FvmOutput::Sparse(SparseFvm {
                                name: "fvm.sparse".into(),
                                filesystems: vec![
                                    "empty-data".to_string(),
                                    "blob".to_string(),
                                    "internal".to_string(),
                                ],
                                max_disk_size: Some(2345),
                            }),
                            FvmOutput::Standard(StandardFvm {
                                name: "fvm.fastboot".into(),
                                filesystems: vec![
                                    "empty-data".to_string(),
                                    "blob".to_string(),
                                    "internal".to_string(),
                                ],
                                compress: true,
                                resize_image_file_to_fit: true,
                                truncate_to_length: Some(3456),
                            }),
                        ],
                    }),
                ],
            }
        );
    }

    #[test]
    fn from_product_and_board_fvm_nand() {
        let board = test_board_config_nand();
        let product = pfc::ProductFilesystemConfig {
            image_name: pfc::ImageName("a-product".into()),
            watch_for_nand: false,
            format_data_on_corruption: pfc::FormatDataOnCorruption(true),
            no_zxcrypt: false,
            image_mode: pfc::FilesystemImageMode::Partition,
            volume: pfc::VolumeConfig::Fvm(pfc::FvmVolumeConfig {
                data: Some(pfc::DataFvmVolumeConfig {
                    use_disk_based_minfs_migration: true,
                    data_filesystem_format: pfc::DataFilesystemFormat::Minfs,
                }),
                blob: Some(pfc::BlobFvmVolumeConfig { blob_layout: BlobfsLayout::Compact }),
                reserved: Some(pfc::ReservedFvmVolumeConfig { reserved_slices: 7 }),
            }),
        };

        let images = ImagesConfig::from_product_and_board(&product, &board).unwrap();
        assert_eq!(
            images,
            ImagesConfig {
                images: vec![
                    Image::Zbi(Zbi {
                        name: "a-product".into(),
                        compression: bfc::ZbiCompression::ZStd,
                        postprocessing_script: Some(bfc::PostProcessingScript {
                            path: "path/to/script".into(),
                            args: vec!["arg1".into(), "arg2".into()],
                        }),
                    }),
                    Image::VBMeta(VBMeta {
                        name: "a-product".into(),
                        key: "path/to/key".into(),
                        key_metadata: "path/to/metadata".into(),
                        additional_descriptors: vec![],
                    }),
                    Image::Fvm(Fvm {
                        slice_size: 5678,
                        filesystems: vec![
                            FvmFilesystem::EmptyData(EmptyData { name: "empty-data".into() }),
                            FvmFilesystem::BlobFS(BlobFS {
                                name: "blob".into(),
                                layout: BlobfsLayout::Compact,
                                maximum_bytes: Some(34),
                                minimum_inodes: Some(56),
                                minimum_data_bytes: Some(78),
                                maximum_contents_size: Some(12),
                            }),
                            FvmFilesystem::Reserved(Reserved {
                                name: "internal".into(),
                                slices: 7,
                            }),
                        ],
                        outputs: vec![
                            FvmOutput::Standard(StandardFvm {
                                name: "fvm".into(),
                                filesystems: vec![
                                    "empty-data".to_string(),
                                    "blob".to_string(),
                                    "internal".to_string(),
                                ],
                                compress: false,
                                resize_image_file_to_fit: false,
                                truncate_to_length: None,
                            }),
                            FvmOutput::Sparse(SparseFvm {
                                name: "fvm.sparse".into(),
                                filesystems: vec![
                                    "empty-data".to_string(),
                                    "blob".to_string(),
                                    "internal".to_string(),
                                ],
                                max_disk_size: Some(2345),
                            }),
                            FvmOutput::Nand(NandFvm {
                                name: "fvm.fastboot".into(),
                                filesystems: vec![
                                    "empty-data".to_string(),
                                    "blob".to_string(),
                                    "internal".to_string(),
                                ],
                                max_disk_size: Some(3456),
                                compress: true,
                                block_count: 1,
                                oob_size: 2,
                                page_size: 3,
                                pages_per_block: 4,
                            }),
                        ],
                    }),
                ],
            }
        );
    }

    #[test]
    fn zbi_compression_try_from() {
        assert_eq!(ZbiCompression::ZStd, "zstd".try_into().unwrap());
        assert_eq!(ZbiCompression::ZStdMax, "zstd.max".try_into().unwrap());
        let compression: Result<ZbiCompression> = "else".try_into();
        assert!(compression.is_err());
    }

    #[test]
    fn zbi_compression_from_string() {
        assert_eq!(ZbiCompression::ZStd, ZbiCompression::from_str("zstd").unwrap());
        assert_eq!(ZbiCompression::ZStdMax, ZbiCompression::from_str("zstd.max").unwrap());
        let compression: Result<ZbiCompression> = ZbiCompression::from_str("else");
        assert!(compression.is_err());
    }

    #[test]
    fn zbi_compressoin_to_string() {
        assert_eq!("zstd".to_string(), ZbiCompression::ZStd.to_string());
        assert_eq!("zstd.max".to_string(), ZbiCompression::ZStdMax.to_string());
    }

    #[test]
    fn blobfs_layout_try_from() {
        assert_eq!(BlobfsLayout::Compact, "compact".try_into().unwrap());
        assert_eq!(BlobfsLayout::DeprecatedPadded, "deprecated_padded".try_into().unwrap());
        let layout: Result<BlobfsLayout> = "else".try_into();
        assert!(layout.is_err());
    }

    #[test]
    fn blobfs_layout_from_string() {
        assert_eq!(BlobfsLayout::Compact, BlobfsLayout::from_str("compact").unwrap());
        assert_eq!(
            BlobfsLayout::DeprecatedPadded,
            BlobfsLayout::from_str("deprecated_padded").unwrap()
        );
        let layout: Result<BlobfsLayout> = BlobfsLayout::from_str("else");
        assert!(layout.is_err());
    }

    #[test]
    fn blobfs_layout_to_string() {
        assert_eq!("compact".to_string(), BlobfsLayout::Compact.to_string());
        assert_eq!("deprecated_padded".to_string(), BlobfsLayout::DeprecatedPadded.to_string());
    }

    #[test]
    fn from_json() {
        let json = r#"
            {
                images: [
                    {
                        type: "zbi",
                        name: "fuchsia",
                        compression: "zstd.max",
                        postprocessing_script: {
                            path: "path/to/tool.sh",
                            args: [ "arg1", "arg2" ]
                        }
                    },
                    {
                        type: "vbmeta",
                        name: "fuchsia",
                        key: "path/to/key",
                        key_metadata: "path/to/key/metadata",
                        additional_descriptors: [
                            {
                                name: "zircon",
                                size: 12345,
                                flags: 1,
                                min_avb_version: "1.1"
                            }
                        ]
                    },
                    {
                        type: "fvm",
                        slice_size: 0,
                        filesystems: [
                            {
                                type: "blobfs",
                                name: "blob",
                                layout: "compact",
                                maximum_bytes: 0,
                                minimum_data_bytes: 0,
                                minimum_inodes: 0,
                            },
                            {
                                type: "reserved",
                                name: "internal",
                                slices: 0,
                            },
                        ],
                        outputs: [
                            {
                                type: "standard",
                                name: "fvm",
                                filesystems: [
                                    "blob",
                                    "data",
                                    "internal",
                                ],
                                resize_image_file_to_fit: true,
                                truncate_to_length: 0,
                            },
                            {
                                type: "sparse",
                                name: "fvm.sparse",
                                filesystems: [
                                    "blob",
                                    "data",
                                    "internal",
                                ],
                                max_disk_size: 0,
                            },
                            {
                                type: "nand",
                                name: "fvm.nand",
                                filesystems: [
                                    "blob",
                                    "data",
                                    "internal",
                                ],
                                compress: true,
                                max_disk_size: 0,
                                block_count: 0,
                                oob_size: 0,
                                page_size: 0,
                                pages_per_block: 0,
                            },
                        ],
                    },
                ],
            }
        "#;
        let mut cursor = std::io::Cursor::new(json);
        let config: ImagesConfig = ImagesConfig::from_reader(&mut cursor).unwrap();
        assert_eq!(config.images.len(), 3);

        let mut found_zbi = false;
        let mut found_vbmeta = false;
        let mut found_standard_fvm = false;
        let mut found_fxfs = false;
        for image in config.images {
            match image {
                Image::Zbi(zbi) => {
                    found_zbi = true;
                    assert_eq!(zbi.name, "fuchsia");
                    assert!(matches!(zbi.compression, ZbiCompression::ZStdMax));
                }
                Image::VBMeta(vbmeta) => {
                    found_vbmeta = true;
                    assert_eq!(vbmeta.name, "fuchsia");
                    assert_eq!(vbmeta.key, PathBuf::from("path/to/key"));
                }
                Image::Fvm(fvm) => {
                    assert_eq!(fvm.outputs.len(), 3);

                    for output in fvm.outputs {
                        match output {
                            FvmOutput::Standard(standard) => {
                                found_standard_fvm = true;
                                assert_eq!(standard.name, "fvm");
                                assert_eq!(standard.filesystems.len(), 3);
                            }
                            _ => {}
                        }
                    }
                }
                Image::Fxfs(_) => {
                    found_fxfs = true;
                }
            }
        }
        assert!(found_zbi);
        assert!(found_vbmeta);
        assert!(found_standard_fvm);
        assert!(!found_fxfs);
    }

    #[test]
    fn using_defaults() {
        let json = r#"
            {
                images: [
                    {
                        type: "zbi",
                    },
                    {
                        type: "vbmeta",
                        key: "path/to/key",
                        key_metadata: "path/to/key/metadata",
                    },
                    {
                        type: "fvm",
                        filesystems: [
                            {
                                type: "blobfs",
                                name: "blob",
                            },
                            {
                                type: "reserved",
                                name: "internal",
                                slices: 0,
                            },
                        ],
                        outputs: [
                            {
                                type: "standard",
                                name: "fvm.blk",
                                filesystems: [
                                    "blob",
                                    "data",
                                    "internal",
                                ],
                            },
                            {
                                type: "sparse",
                                name: "fvm.sparse.blk",
                                filesystems: [
                                    "blob",
                                    "data",
                                    "internal",
                                ],
                            },
                            {
                                type: "nand",
                                name: "fvm.fastboot.blk",
                                filesystems: [
                                    "blob",
                                    "data",
                                    "internal",
                                ],
                                block_count: 0,
                                oob_size: 0,
                                page_size: 0,
                                pages_per_block: 0,
                            },
                        ],
                    },
                ],
            }
        "#;
        let mut cursor = std::io::Cursor::new(json);
        let config: ImagesConfig = ImagesConfig::from_reader(&mut cursor).unwrap();
        assert_eq!(config.images.len(), 3);
    }
}
