// Copyright 2020 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::{Error, Result},
    byteorder::{LittleEndian, ReadBytesExt},
    log::info,
    serde::{Deserialize, Serialize},
    std::collections::HashMap,
    std::convert::{TryFrom, TryInto},
    std::fmt,
    std::io::{Cursor, Read, Seek, SeekFrom},
    std::str,
    thiserror::Error,
};

const FVM_MAGIC: u64 = 0x54524150204d5646;
const FVM_VERSION: u64 = 0x00000001;
const FVM_BLOCK_SIZE: u64 = 8192;
const FVM_MAX_VPARTITION_NAME_LEN: usize = 24;
const FVM_MAX_VPARTITIONS: usize = 1024;
const SHA256_BYTE_LEN: usize = 32;
const GPT_GUID_LEN: usize = 16;
// Masks and constants required to extract the opaque slice entry data.
const SLICE_ENTRY_VPARTITION_BITS: u64 = 16;
const SLICE_ENTRY_VSLICE_BITS: u64 = 32;
const SLICE_ENTRY_VSLICE_MAX: u64 = (1 << SLICE_ENTRY_VSLICE_BITS) - 1;
const SLICE_ENTRY_VSLICE_MASK: u64 = SLICE_ENTRY_VSLICE_MAX << SLICE_ENTRY_VPARTITION_BITS;
const VPARTITION_ENTRY_MASK: u64 = (1 << SLICE_ENTRY_VPARTITION_BITS) - 1;

/// The set of supported FVM partition types.
#[derive(Debug, PartialEq, Eq, Hash)]
pub enum FvmPartitionType {
    MinFs,
    BlobFs,
}

impl fmt::Display for FvmPartitionType {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match &self {
            FvmPartitionType::MinFs => write!(f, "minfs"),
            FvmPartitionType::BlobFs => write!(f, "blobfs"),
        }
    }
}

/// The FvmPartition represents a contiguous typed partition. The buffer
/// represents the entire set of vslices for the partition merged into a single
/// buffer. This representation is obviously memory intensive but is currently
/// designed for small buffers less than 1GB.
#[derive(Debug)]
pub struct FvmPartition {
    pub partition_type: FvmPartitionType,
    pub buffer: Vec<u8>,
}

/// Defines the FvmHeader for a particular partition. In this case we are
/// parsing the structure using a cursor so this structure doesn't have to
/// directly match the underlying type.
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
struct FvmHeader {
    magic: u64,
    version: u64,
    pslice_count: u64,
    slice_size: u64,
    fvm_partition_size: u64, // Total size of this partition.
    vpartition_table_size: u64,
    allocation_table_size: u64,
    generation: u64,
    hash: Vec<u8>,
}

impl FvmHeader {
    /// Parses the entire FVM header from a binary cursor. This function will
    /// error if either the cursor ends before it is expected to or the magic
    /// number provided in the header is incorrect.
    pub fn parse(cursor: &mut Cursor<Vec<u8>>) -> Result<Self> {
        let starting_pos: i64 = cursor.position().try_into()?;
        let magic: u64 = cursor.read_u64::<LittleEndian>()?;
        if magic != FVM_MAGIC {
            return Err(Error::new(FvmError::InvalidHeaderMagic));
        }
        let version: u64 = cursor.read_u64::<LittleEndian>()?;
        if version != FVM_VERSION {
            return Err(Error::new(FvmError::UnsupportedVersion));
        }
        let pslice_count: u64 = cursor.read_u64::<LittleEndian>()?;
        let slice_size: u64 = cursor.read_u64::<LittleEndian>()?;
        let fvm_partition_size: u64 = cursor.read_u64::<LittleEndian>()?;
        let vpartition_table_size: u64 = cursor.read_u64::<LittleEndian>()?;
        let allocation_table_size: u64 = cursor.read_u64::<LittleEndian>()?;
        let generation: u64 = cursor.read_u64::<LittleEndian>()?;
        let mut hash = vec![0u8; SHA256_BYTE_LEN];
        cursor.read_exact(&mut hash)?;

        // The FVM Header sits in a superblock so is padded for FVM_BLOCK_SIZE
        // at the end of the structure.
        let ending_pos: i64 = cursor.position().try_into()?;
        let header_len: i64 = ending_pos - starting_pos;
        if header_len < FVM_BLOCK_SIZE.try_into()? {
            let padding: i64 = i64::try_from(FVM_BLOCK_SIZE)? - header_len;
            cursor.seek(SeekFrom::Current(padding))?;
        }

        Ok(Self {
            magic,
            version,
            pslice_count,
            slice_size,
            fvm_partition_size,
            vpartition_table_size,
            allocation_table_size,
            generation,
            hash,
        })
    }
}

/// Represents an entry in the FVM partition table which is a fixed contiguous
/// flat buffer.
#[allow(dead_code)]
pub struct VPartitionEntry {
    partition_type: Vec<u8>,
    guid: Vec<u8>,
    slices: u32,
    flags: u32,
    unsafe_name: Vec<u8>,
}

impl VPartitionEntry {
    pub fn parse(cursor: &mut Cursor<Vec<u8>>) -> Result<Self> {
        let mut partition_type = vec![0u8; GPT_GUID_LEN];
        cursor.read_exact(&mut partition_type)?;
        let mut guid = vec![0u8; GPT_GUID_LEN];
        cursor.read_exact(&mut guid)?;
        let slices: u32 = cursor.read_u32::<LittleEndian>()?;
        let flags: u32 = cursor.read_u32::<LittleEndian>()?;
        let mut unsafe_name = vec![0u8; FVM_MAX_VPARTITION_NAME_LEN];
        cursor.read_exact(&mut unsafe_name)?;
        Ok(Self { partition_type, guid, slices, flags, unsafe_name })
    }
}

#[allow(dead_code)]
pub struct SliceEntry {
    data: u64,
}

impl SliceEntry {
    pub fn parse(cursor: &mut Cursor<Vec<u8>>) -> Result<Self> {
        Ok(Self { data: cursor.read_u64::<LittleEndian>()? })
    }

    pub fn is_allocated(&self) -> bool {
        self.vpartition() != 0
    }

    pub fn vslice(&self) -> u64 {
        (self.data & SLICE_ENTRY_VSLICE_MASK) >> SLICE_ENTRY_VPARTITION_BITS
    }

    pub fn vpartition(&self) -> u64 {
        self.data & VPARTITION_ENTRY_MASK
    }
}

#[derive(Error, Debug, PartialEq, Eq)]
pub enum FvmError {
    #[error("Fvm header magic value doesn't match expected value")]
    InvalidHeaderMagic,
    #[error("Fvm header version is not supported")]
    UnsupportedVersion,
}

/// The FvmReader parses the SuperBlock which fits inside a single block.
/// Following the SuperBlock is the Virtual Partition Table followed directly
/// by the Allocation Table. The reader will return a vector of FvmPartitions
/// which contain a filesystem type and the "virtual" representation of the
/// partition (sorted pslices by vslice).
pub struct FvmReader {
    cursor: Cursor<Vec<u8>>,
}

impl FvmReader {
    /// Constructs a new reader from an existing fvm_buffer.
    pub fn new(fvm_buffer: Vec<u8>) -> Self {
        Self { cursor: Cursor::new(fvm_buffer) }
    }

    /// Parses the FVM provided during construction returning the set of
    /// partitions as buffers ordered by vslice.
    pub fn parse(&mut self) -> Result<Vec<FvmPartition>> {
        // Parse the SuperBlock header which always fits inside one block.
        let header = FvmHeader::parse(&mut self.cursor)?;
        // Read the partition table that directly follows the super block.
        let mut partitions = Vec::with_capacity(FVM_MAX_VPARTITIONS);
        for _i in 0..FVM_MAX_VPARTITIONS {
            partitions.push(VPartitionEntry::parse(&mut self.cursor)?);
        }
        // The actual number of entries in the table.
        let allocation_entries = header.fvm_partition_size / header.slice_size;
        // The number of bits total that the entire allocation contains.
        let total_allocation_entries = header.allocation_table_size / 8;
        let padding_entries = total_allocation_entries - allocation_entries;

        // Load in all the slice allocations from the alloctaion table.
        let mut allocations = Vec::with_capacity(allocation_entries.try_into()?);
        for _i in 0..allocation_entries {
            let slice = SliceEntry::parse(&mut self.cursor)?;
            allocations.push(slice);
        }
        // Push the cursor to the end of the block, ignore these allocation
        // entries they are just padding.
        for _i in 0..padding_entries {
            let _ = SliceEntry::parse(&mut self.cursor);
        }
        // Calculate mapping from partition_id -> (vslice, allocation_index)
        let mut partition_alloc_map: HashMap<u64, Vec<(u64, u64)>> = HashMap::new();
        let mut allocation_index = 0;
        for slice in allocations {
            if slice.is_allocated() {
                if !partition_alloc_map.contains_key(&slice.vpartition()) {
                    partition_alloc_map
                        .insert(slice.vpartition(), vec![(slice.vslice(), allocation_index)]);
                } else {
                    partition_alloc_map
                        .get_mut(&slice.vpartition())
                        .unwrap()
                        .push((slice.vslice(), allocation_index));
                }
            }
            allocation_index += 1;
        }
        // Sort the allocations by vslice 0 -> max, this uses the property that
        // 2-tuple pairs are first sorted by their 1st param then their second.
        for (_, v) in partition_alloc_map.iter_mut() {
            v.sort();
        }

        // Convert the internal fragmented pslice allocation format to a
        // simple contiguous buffer. This is the "virtual" representation per
        // partition as informed by the sorted partition_alloc_map.
        let mut fvm_partitions = vec![];
        // Two copies of the metadata are always stored at the start of the FVM.
        let slice_section_start = 2 * self.cursor.position();
        self.cursor.seek(SeekFrom::Start(slice_section_start))?;

        for (partition_index, vslice_pslice_mappings) in partition_alloc_map.iter() {
            let idx = partition_index.clone() as usize;
            let idx = usize::try_from(idx)?;
            if let Ok(name) = str::from_utf8(&partitions[idx].unsafe_name) {
                let fs_type = if name.starts_with("blobfs") {
                    info!("FVM: Found BlobFS volume with {} slices", vslice_pslice_mappings.len());
                    Some(FvmPartitionType::BlobFs)
                } else if name.starts_with("minfs") {
                    info!("FVM: Found Minfs volume with {} slices", vslice_pslice_mappings.len());
                    Some(FvmPartitionType::MinFs)
                } else {
                    None
                };

                // Only create FVM file systems from known types.
                if let Some(fs_type) = fs_type {
                    // Note that the mappings are in sorted order already.
                    let mut partition_buffer = vec![];
                    for (vslice, pslice) in vslice_pslice_mappings.iter() {
                        self.cursor.seek(SeekFrom::Start(slice_section_start))?;
                        let offset = i64::try_from((pslice - 1) * header.slice_size)?;
                        info!(
                            "Seeking: {} {} {}",
                            vslice,
                            pslice,
                            slice_section_start + (pslice - 1) * header.slice_size
                        );
                        self.cursor.seek(SeekFrom::Current(offset))?;
                        let mut slice_buffer = vec![1; header.slice_size as usize];
                        self.cursor.read(&mut slice_buffer)?;
                        partition_buffer.append(&mut slice_buffer);
                    }
                    fvm_partitions
                        .push(FvmPartition { partition_type: fs_type, buffer: partition_buffer });
                }
            }
        }

        Ok(fvm_partitions)
    }
}

#[cfg(test)]
mod tests {
    use {super::*, std::convert::TryFrom};

    #[test]
    fn test_fvm_magic_invalid() {
        let header_invalid_magic = FvmHeader {
            magic: 1,
            version: FVM_VERSION,
            pslice_count: 1,
            slice_size: FVM_BLOCK_SIZE,
            fvm_partition_size: FVM_BLOCK_SIZE,
            vpartition_table_size: FVM_BLOCK_SIZE,
            allocation_table_size: FVM_BLOCK_SIZE,
            generation: 0,
            hash: vec![0u8; GPT_GUID_LEN],
        };
        let fvm_bytes = bincode::serialize(&header_invalid_magic).unwrap();
        let mut reader = FvmReader::new(fvm_bytes);
        let result = reader.parse();
        assert_eq!(
            result.unwrap_err().downcast::<FvmError>().unwrap(),
            FvmError::InvalidHeaderMagic
        );
    }

    #[test]
    fn test_fvm_version_invalid() {
        let header_invalid_magic = FvmHeader {
            magic: FVM_MAGIC,
            version: 123,
            pslice_count: 1,
            slice_size: FVM_BLOCK_SIZE,
            fvm_partition_size: FVM_BLOCK_SIZE,
            vpartition_table_size: FVM_BLOCK_SIZE,
            allocation_table_size: FVM_BLOCK_SIZE,
            generation: 0,
            hash: vec![0u8; GPT_GUID_LEN],
        };
        let fvm_bytes = bincode::serialize(&header_invalid_magic).unwrap();
        let mut reader = FvmReader::new(fvm_bytes);
        let result = reader.parse();
        assert_eq!(
            result.unwrap_err().downcast::<FvmError>().unwrap(),
            FvmError::UnsupportedVersion
        );
    }

    #[test]
    fn test_fvm_truncated_header() {
        let header_invalid_magic = FvmHeader {
            magic: FVM_MAGIC,
            version: FVM_VERSION,
            pslice_count: 1,
            slice_size: FVM_BLOCK_SIZE,
            fvm_partition_size: FVM_BLOCK_SIZE,
            vpartition_table_size: FVM_BLOCK_SIZE,
            allocation_table_size: FVM_BLOCK_SIZE,
            generation: 0,
            hash: vec![0u8; GPT_GUID_LEN],
        };
        let mut fvm_bytes = bincode::serialize(&header_invalid_magic).unwrap();
        fvm_bytes.pop();
        let mut reader = FvmReader::new(fvm_bytes);
        let result = reader.parse();
        assert_eq!(result.is_err(), true);
    }

    #[test]
    fn test_fvm_empty() {
        let header_invalid_magic = FvmHeader {
            magic: FVM_MAGIC,
            version: FVM_VERSION,
            pslice_count: 1,
            slice_size: FVM_BLOCK_SIZE,
            fvm_partition_size: FVM_BLOCK_SIZE,
            vpartition_table_size: FVM_BLOCK_SIZE,
            allocation_table_size: FVM_BLOCK_SIZE,
            generation: 0,
            hash: vec![0u8; GPT_GUID_LEN],
        };
        let mut fvm_bytes = bincode::serialize(&header_invalid_magic).unwrap();
        let mut padding = vec![0u8; usize::try_from(FVM_BLOCK_SIZE * 32).unwrap()];
        fvm_bytes.append(&mut padding);
        let mut reader = FvmReader::new(fvm_bytes);
        let result = reader.parse();
        assert_eq!(result.is_ok(), true);
    }
}
