// Copyright 2022, The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Support for the pvmfw configuration data format.

use core::fmt;
use core::mem;
use core::num::NonZeroUsize;
use core::ops::Range;
use core::result;
use core::slice;
use log::{info, warn};
use static_assertions::const_assert_eq;
use vmbase::util::RangeExt;
use zerocopy::{FromBytes, FromZeroes, LayoutVerified};

/// Configuration data header.
#[repr(C, packed)]
#[derive(Clone, Copy, Debug, FromZeroes, FromBytes)]
struct Header {
    /// Magic number; must be `Header::MAGIC`.
    magic: u32,
    /// Version of the header format.
    version: Version,
    /// Total size of the configuration data.
    total_size: u32,
    /// Feature flags; currently reserved and must be zero.
    flags: u32,
}

#[derive(Debug)]
pub enum Error {
    /// Reserved region can't fit configuration header.
    BufferTooSmall,
    /// Header has the wrong alignment
    HeaderMisaligned,
    /// Header doesn't contain the expect magic value.
    InvalidMagic,
    /// Version of the header isn't supported.
    UnsupportedVersion(Version),
    /// Header describes configuration data that doesn't fit in the expected buffer.
    InvalidSize(usize),
    /// Header entry is missing.
    MissingEntry(Entry),
    /// Range described by entry does not fit within config data.
    EntryOutOfBounds(Entry, Range<usize>, Range<usize>),
    /// Entries are in out of order
    EntryOutOfOrder,
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            Self::BufferTooSmall => write!(f, "Reserved region is smaller than config header"),
            Self::HeaderMisaligned => write!(f, "Reserved region is misaligned"),
            Self::InvalidMagic => write!(f, "Wrong magic number"),
            Self::UnsupportedVersion(v) => write!(f, "Version {v} not supported"),
            Self::InvalidSize(sz) => write!(f, "Total size ({sz:#x}) overflows reserved region"),
            Self::MissingEntry(entry) => write!(f, "Mandatory {entry:?} entry is missing"),
            Self::EntryOutOfBounds(entry, range, limits) => {
                write!(
                    f,
                    "Entry {entry:?} out of bounds: {range:#x?} must be within range {limits:#x?}"
                )
            }
            Self::EntryOutOfOrder => write!(f, "Entries are out of order"),
        }
    }
}

pub type Result<T> = result::Result<T, Error>;

impl Header {
    const MAGIC: u32 = u32::from_ne_bytes(*b"pvmf");
    const VERSION_1_0: Version = Version { major: 1, minor: 0 };
    const VERSION_1_1: Version = Version { major: 1, minor: 1 };

    pub fn total_size(&self) -> usize {
        self.total_size as usize
    }

    pub fn body_lowest_bound(&self) -> Result<usize> {
        let entries_offset = mem::size_of::<Self>();

        // Ensure that the entries are properly aligned and do not require padding.
        const_assert_eq!(mem::align_of::<Header>() % mem::align_of::<HeaderEntry>(), 0);
        const_assert_eq!(mem::size_of::<Header>() % mem::align_of::<HeaderEntry>(), 0);

        let entries_size = self.entry_count()?.checked_mul(mem::size_of::<HeaderEntry>()).unwrap();

        Ok(entries_offset.checked_add(entries_size).unwrap())
    }

    pub fn entry_count(&self) -> Result<usize> {
        let last_entry = match self.version {
            Self::VERSION_1_0 => Entry::DebugPolicy,
            Self::VERSION_1_1 => Entry::VmDtbo,
            v @ Version { major: 1, .. } => {
                const LATEST: Version = Header::VERSION_1_1;
                warn!("Parsing unknown config data version {v} as version {LATEST}");
                return Ok(Entry::COUNT);
            }
            v => return Err(Error::UnsupportedVersion(v)),
        };

        Ok(last_entry as usize + 1)
    }
}

#[derive(Clone, Copy, Debug)]
pub enum Entry {
    Bcc,
    DebugPolicy,
    VmDtbo,
    #[allow(non_camel_case_types)] // TODO: Use mem::variant_count once stable.
    _VARIANT_COUNT,
}

impl Entry {
    const COUNT: usize = Self::_VARIANT_COUNT as usize;
}

#[derive(Default)]
pub struct Entries<'a> {
    pub bcc: &'a mut [u8],
    pub debug_policy: Option<&'a mut [u8]>,
    pub vm_dtbo: Option<&'a mut [u8]>,
}

#[repr(packed)]
#[derive(Clone, Copy, Debug, FromZeroes, FromBytes)]
struct HeaderEntry {
    offset: u32,
    size: u32,
}

#[repr(C, packed)]
#[derive(Clone, Copy, Debug, Eq, FromZeroes, FromBytes, PartialEq)]
pub struct Version {
    minor: u16,
    major: u16,
}

impl fmt::Display for Version {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // Copy the fields to local variables to prevent unaligned access.
        let (major, minor) = (self.major, self.minor);
        write!(f, "{}.{}", major, minor)
    }
}

/// Range with non-empty length.
#[derive(Debug, Copy, Clone)]
struct NonEmptyRange {
    start: usize,
    size: NonZeroUsize,
}

impl NonEmptyRange {
    pub fn new(start: usize, size: usize) -> Option<Self> {
        // Ensure end() is safe.
        start.checked_add(size).unwrap();

        Some(Self { start, size: NonZeroUsize::new(size)? })
    }

    fn end(&self) -> usize {
        self.start + self.len()
    }

    fn len(&self) -> usize {
        self.size.into()
    }

    fn as_range(&self) -> Range<usize> {
        self.start..self.end()
    }
}

#[derive(Debug)]
pub struct Config<'a> {
    body: &'a mut [u8],
    ranges: [Option<NonEmptyRange>; Entry::COUNT],
}

impl<'a> Config<'a> {
    /// Take ownership of a pvmfw configuration consisting of its header and following entries.
    pub fn new(bytes: &'a mut [u8]) -> Result<Self> {
        const HEADER_SIZE: usize = mem::size_of::<Header>();
        if bytes.len() < HEADER_SIZE {
            return Err(Error::BufferTooSmall);
        }

        let (header, rest) =
            LayoutVerified::<_, Header>::new_from_prefix(bytes).ok_or(Error::HeaderMisaligned)?;
        let header = header.into_ref();

        if header.magic != Header::MAGIC {
            return Err(Error::InvalidMagic);
        }

        let header_flags = header.flags;
        if header_flags != 0 {
            warn!("Ignoring unknown config flags: {header_flags:#x}");
        }

        info!("pvmfw config version: {}", header.version);

        // Validate that we won't get an invalid alignment in the following due to padding to u64.
        const_assert_eq!(HEADER_SIZE % mem::size_of::<u64>(), 0);

        // Ensure that Header::total_size isn't larger than anticipated by the caller and resize
        // the &[u8] to catch OOB accesses to entries/blobs.
        let total_size = header.total_size();
        let rest = if let Some(rest_size) = total_size.checked_sub(HEADER_SIZE) {
            rest.get_mut(..rest_size).ok_or(Error::InvalidSize(total_size))?
        } else {
            return Err(Error::InvalidSize(total_size));
        };

        let (header_entries, body) =
            LayoutVerified::<_, [HeaderEntry]>::new_slice_from_prefix(rest, header.entry_count()?)
                .ok_or(Error::BufferTooSmall)?;

        // Validate that we won't get an invalid alignment in the following due to padding to u64.
        const_assert_eq!(mem::size_of::<HeaderEntry>() % mem::size_of::<u64>(), 0);

        // Ensure entries are in the body.
        let limits = header.body_lowest_bound()?..total_size;
        let mut ranges: [Option<NonEmptyRange>; Entry::COUNT] = [None; Entry::COUNT];
        let mut last_end = 0;
        for entry in [Entry::Bcc, Entry::DebugPolicy, Entry::VmDtbo] {
            let Some(header_entry) = header_entries.get(entry as usize) else { continue };
            let entry_offset = header_entry.offset.try_into().unwrap();
            let entry_size = header_entry.size.try_into().unwrap();
            let Some(range) = NonEmptyRange::new(entry_offset, entry_size) else { continue };
            let range = range.as_range();
            if !range.is_within(&limits) {
                return Err(Error::EntryOutOfBounds(entry, range, limits));
            }

            if last_end > range.start {
                return Err(Error::EntryOutOfOrder);
            }
            last_end = range.end;

            ranges[entry as usize] = NonEmptyRange::new(
                entry_offset - limits.start, // is_within() validates safety of this.
                entry_size,
            );
        }
        // Ensures that BCC exists.
        ranges[Entry::Bcc as usize].ok_or(Error::MissingEntry(Entry::Bcc))?;

        Ok(Self { body, ranges })
    }

    /// Get slice containing the platform BCC.
    pub fn get_entries(&mut self) -> Entries<'_> {
        // This assumes that the blobs are in-order w.r.t. the entries.
        let bcc_range = self.get_entry_range(Entry::Bcc);
        let dp_range = self.get_entry_range(Entry::DebugPolicy);
        let vm_dtbo_range = self.get_entry_range(Entry::VmDtbo);
        // TODO(b/291191157): Provision device assignment with this.
        if let Some(vm_dtbo_range) = vm_dtbo_range {
            info!("Found VM DTBO at {:?}", vm_dtbo_range);
        }

        // SAFETY: When instantiated, ranges are validated to be in the body range without
        // overlapping.
        let (bcc, debug_policy, vm_dtbo) = unsafe {
            let ptr = self.body.as_mut_ptr() as usize;
            (
                Self::from_raw_range_mut(ptr, bcc_range.unwrap()),
                dp_range.map(|dp_range| Self::from_raw_range_mut(ptr, dp_range)),
                vm_dtbo_range.map(|vm_dtbo_range| Self::from_raw_range_mut(ptr, vm_dtbo_range)),
            )
        };
        Entries { bcc, debug_policy, vm_dtbo }
    }

    fn get_entry_range(&self, entry: Entry) -> Option<NonEmptyRange> {
        self.ranges[entry as usize]
    }

    unsafe fn from_raw_range_mut(ptr: usize, range: NonEmptyRange) -> &'a mut [u8] {
        // SAFETY: The caller must ensure that the range is valid from ptr.
        unsafe { slice::from_raw_parts_mut((ptr + range.start) as *mut u8, range.len()) }
    }
}
