use crate::boot_services::BootServicesTable;
use crate::simple_text_output::SimpleTextOutputProtocol;
use crate::structs::*;
use crate::types::Handle;

#[repr(C)]
pub struct SystemTable {
    /// The table header for the EFI System Table. This header contains the EFI_SYSTEM_TABLE_SIGNATURE and EFI_SYSTEM_TABLE_REVISION values along with the size of the EFI_SYSTEM_TABLE structure and a 32-bit CRC to verify that the contents of the EFI System Table are valid.
    pub efi_table_header: TableHeader,
    /// A pointer to a null terminated string that identifies the vendor that produces the system firmware for the platform.
    pub firmware_vendor: *mut u16,
    /// A firmware vendor specific value that identifies the revision of the system firmware for the platform.
    pub firmware_revision: SystemTableRevisions,
    /// The handle for the active console input device. This handle must support EFI_SIMPLE_TEXT_INPUT_PROTOCOL and EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL. If there is no active console, these protocols must still be present.
    pub console_in_handle: Handle,
    /// A pointer to the EFI_SIMPLE_TEXT_INPUT_PROTOCOL interface that is associated with ConsoleInHandle.
    pub console_in: *mut SimpleTextInputProtocol,
    /// The handle for the active console output device. This handle must support the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL. If there is no active console, this protocol must still be present.
    pub console_out_handle: Handle,
    /// A pointer to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL interface that is associated with ConsoleOutHandle.
    pub console_out: *mut SimpleTextOutputProtocol,
    /// The handle for the active standard error console device. This handle must support the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL. If there is no active console, this protocol must still be present.
    pub standard_error_handle: Handle,
    /// A pointer to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL interface that is associated with StandardErrorHandle.
    pub standard_error: *mut SimpleTextOutputProtocol,
    /// A pointer to the EFI Runtime Services Table.
    pub runtime_services_table_pointer: *mut RuntimeServicesTable,
    /// A pointer to the EFI Boot Services Table.
    pub boot_services_table_pointer: *mut BootServicesTable,
    /// The number of system configuration tables in the buffer ConfigurationTable.
    pub number_of_table_entries: usize,
    /// A pointer to the system configuration tables. The number of entries in the table is NumberOfTableEntries.
    pub configuration_table: ConfigurationTable,
    // ACPIConfigurationTablePointer: *mut ACPIConfigurationTable,
    // SMBIOSConfigurationTable: *mut SMBIOSConfigurationTable,
    // SALSystemTable: *mut SALSystemTable
}

impl SystemTable {
    pub const SYSTEM_TABLE_SIGNATURE: u64 = 0x5453595320494249;
}

#[repr(C)]
pub struct ImageEntryPoint {
    image_handle: *const i32, // The firmware allocated handle for the UEFI image.
    system_table_pointer: *const i32, // A pointer to the EFI System Table.
}

#[repr(u32)]
pub enum SystemTableRevisions {
    EFI2_100SystemTableRevision = (2 << 16) | 100,
    EFI1_90SystemTableRevision = ((2 << 16) | (90)),
    EFI1_80SystemTableRevision = ((2 << 16) | (80)),
    EFI1_70SystemTableRevision = ((2 << 16) | (70)),
    EFI1_60SystemTableRevision = ((2 << 16) | (60)),
    EFI1_50SystemTableRevision = ((2 << 16) | (50)),
    EFI1_40SystemTableRevision = ((2 << 16) | (40)),
    EFI1_31SystemTableRevision = ((2 << 16) | (31)),
    EFI1_30SystemTableRevision = ((2 << 16) | (30)),
    EFI1_20SystemTableRevision = ((2 << 16) | (20)),
    EFI1_10SystemTableRevision = ((2 << 16) | (10)),
    EFI1_00SystemTableRevision = ((2 << 16) | (00)),
    EFI0_10SystemTableRevision = ((1 << 16) | (10)),
    EFI0_02SystemTableRevision = ((1 << 16) | (02)),
}
