/// `NULL a s m` as an array of 4 bytes
pub const WASM_BINARY_MAGIC: [u8; 4] = [0x00, 0x61, 0x73, 0x6d];

///  `1 0 0 0` as an array of 4 bytes
pub const WASM_VERSION: [u8; 4] = [0x01, 0x00, 0x00, 0x00];

/// A wasm section
///
/// # Examples
/// ```
/// use wasm_loader::wasm::WasmSection;
/// let section = WasmSection::new(0, vec![0x00, 0x01, 0x02, 0x03]);
/// assert_eq!(section.id, 0);
/// assert_eq!(section.data, vec![0x00, 0x01, 0x02, 0x03]);
/// ```
/// # Notes
/// The wasm spec defines the following section types:
/// * `0`: custom
/// * `1`: type
/// * `2`: import
/// * `3`: function
/// * `4`: table
/// * `5`: memory
/// * `6`: global
/// * `7`: export
/// * `8`: start
/// * `9`: element
/// * `10`: code
/// * `11`: data
pub enum SectionType {
    None = 0,
    Type = 1,
    Import = 2,
    Function = 3,
    Table = 4,
    Memory = 5,
    Global = 6,
    Export = 7,
    Start = 8,
    Element = 9,
    Code = 10,
    Data = 11,
}

pub struct Section {
    /// The section type
    _stype: SectionType,
    _section_size: u8,
}

/// A wasm type
/// # Examples
/// ```
/// use wasm_loader::wasm::WasmType;
/// let type_ = WasmType::new(vec![0x00, 0x01, 0x02, 0x03]);
/// assert_eq!(type_.subtypes, vec![0x00, 0x01, 0x02, 0x03]);
/// ```
/// # Notes
/// The wasm spec defines the following type subtypes:
/// * `0`: anyfunc
/// * `1`: func
/// * `2`: block
/// * `3`: i32
/// * `4`: i64
/// * `5`: f32
/// * `6`: f64
pub enum WasmType {
    Anyfunc = 0,
    Func = 1,
    Block = 2,
    I32 = 3,
    I64 = 4,
    F32 = 5,
    F64 = 6,
}

pub struct WasmProgram {
    raw_bytes: Vec<u8>,
}

impl WasmProgram {
    pub fn new_from_bytes(bytes: &[u8]) -> Self {
        Self {
            raw_bytes: bytes.to_vec(),
        }
    }
    /// Returns the a tuple of two bools
    /// The first bool is true if the wasm binary is valid
    /// The second bool is true if the wasm binary version is 1
    ///
    /// # Examples
    /// ```
    /// use wasm_loader::wasm::WasmProgram;
    /// let wasm_program = WasmProgram::new_from_bytes(b"\0\0\0\01\0\0\0");
    /// assert_eq!(wasm_program.is_valid(), (true, false));
    /// ```
    pub fn validate_header(self) -> (bool, bool) {
        let mut byte_magic_valid = false;
        let mut byte_version_valid = false;

        if self.raw_bytes[0..4] == WASM_BINARY_MAGIC {
            byte_magic_valid = true;
        }

        if self.raw_bytes[4..8] == WASM_VERSION {
            byte_version_valid = true;
        }
        (byte_magic_valid, byte_version_valid)
    }
}
