/*
 * Copyright (c) 2022, able <abl3theabove@gmail.com>
 *
 * SPDX-License-Identifier: MPL-2.0
 */

use core::fmt::Display;

#[derive(PartialEq, Debug, Copy, Clone, Eq)]
#[repr(u16)]
pub enum Vendor {
    ThreeDfxInteractiveInc = 0x121a,
    ThreeDLabs = 0x3d3d,
    AllianceSemiconductorCorp = 0x1142,
    ARKLogicInc = 0xedd8,
    ATITechnologiesInc = 0x1002,
    AvanceLogicIncALI = 0x1005,
    ChipsandTechnologies = 0x102c,
    CirrusLogic = 0x1013,
    Compaq = 0x0e11,
    CyrixCorp = 0x1078,
    DiamondMultimediaSystems = 0x1092,
    DigitalEquipmentCorp = 0x1011,
    Iit = 0x1061,
    IntegratedMicroSolutionsInc = 0x10e0,
    IntelCorp = 0x8086,
    IntergraphicsSystems = 0x10ea,
    MacronixInc = 0x10d9,
    MatroxGraphicsInc = 0x102b,
    MiroComputersProductsAG = 0x1031,
    NationalSemiconductorCorp = 0x100b,
    NeoMagicCorp = 0x10c8,
    Number9ComputerCompany = 0x105d,
    NVidiaCorporation = 0x10de,
    NVidiaSgsthomson = 0x12d2,
    OakTechnologyInc = 0x104e,
    Qemu = 0x1234,
    QuantumDesignsHKLtd = 0x1098,
    Real3D = 0x003d,
    Rendition = 0x1163,
    S3Inc = 0x5333,
    SierraSemiconductor = 0x10a8,
    SiliconIntegratedSystemsSiS = 0x1039,
    SiliconMotionInc = 0x126f,
    STBSystemsInc = 0x10b4,
    TexasInstruments = 0x104c,
    ToshibaAmericaInfoSystems = 0x1179,
    TridentMicrosystems = 0x1023,
    TsengLabsInc = 0x100c,
    TundraSemiconductorCorp = 0x10e3,
    VIATechnologiesInc = 0x1106,
    VirtIO = 0x1AF4,
    VMWareInc = 0x15ad,
    Weitek = 0x100e,
    Unknown(u16),
}

impl From<u16> for Vendor {
    fn from(vendor_id: u16) -> Self {
        use Vendor::*;
        match vendor_id {
            0x121a => ThreeDfxInteractiveInc,
            0x3d3d => ThreeDLabs,
            0x1142 => AllianceSemiconductorCorp,
            0xedd8 => ARKLogicInc,
            0x1002 => ATITechnologiesInc,
            0x1005 => AvanceLogicIncALI,
            0x102c => ChipsandTechnologies,
            0x1013 => CirrusLogic,
            0x0e11 => Compaq,
            0x1078 => CyrixCorp,
            0x1092 => DiamondMultimediaSystems,
            0x1011 => DigitalEquipmentCorp,
            0x1061 => Iit,
            0x10e0 => IntegratedMicroSolutionsInc,
            0x8086 => IntelCorp,
            0x10ea => IntergraphicsSystems,
            0x10d9 => MacronixInc,
            0x102b => MatroxGraphicsInc,
            0x1031 => MiroComputersProductsAG,
            0x100b => NationalSemiconductorCorp,
            0x10c8 => NeoMagicCorp,
            0x105d => Number9ComputerCompany,
            0x10de => NVidiaCorporation,
            0x12d2 => NVidiaSgsthomson,
            0x104e => OakTechnologyInc,
            0x1234 => Qemu,
            0x1098 => QuantumDesignsHKLtd,
            0x003d => Real3D,
            0x1163 => Rendition,
            0x5333 => S3Inc,
            0x10a8 => SierraSemiconductor,
            0x1039 => SiliconIntegratedSystemsSiS,
            0x126f => SiliconMotionInc,
            0x10b4 => STBSystemsInc,
            0x104c => TexasInstruments,
            0x1179 => ToshibaAmericaInfoSystems,
            0x1023 => TridentMicrosystems,
            0x100c => TsengLabsInc,
            0x10e3 => TundraSemiconductorCorp,
            0x1106 => VIATechnologiesInc,
            0x1AF4 => VirtIO,
            0x15ad => VMWareInc,
            0x100e => Weitek,
            id => Unknown(id),
        }
    }
}

impl Into<u16> for Vendor {
    fn into(self) -> u16 {
        use Vendor::*;
        match self {
            ThreeDfxInteractiveInc => 0x121a,
            ThreeDLabs => 0x3d3d,
            AllianceSemiconductorCorp => 0x1142,
            ARKLogicInc => 0xedd8,
            ATITechnologiesInc => 0x1002,
            AvanceLogicIncALI => 0x1005,
            ChipsandTechnologies => 0x102c,
            CirrusLogic => 0x1013,
            Compaq => 0x0e11,
            CyrixCorp => 0x1078,
            DiamondMultimediaSystems => 0x1092,
            DigitalEquipmentCorp => 0x1011,
            Iit => 0x1061,
            IntegratedMicroSolutionsInc => 0x10e0,
            IntelCorp => 0x8086,
            IntergraphicsSystems => 0x10ea,
            MacronixInc => 0x10d9,
            MatroxGraphicsInc => 0x102b,
            MiroComputersProductsAG => 0x1031,
            NationalSemiconductorCorp => 0x100b,
            NeoMagicCorp => 0x10c8,
            Number9ComputerCompany => 0x105d,
            NVidiaCorporation => 0x10de,
            NVidiaSgsthomson => 0x12d2,
            OakTechnologyInc => 0x104e,
            Qemu => 0x1234,
            QuantumDesignsHKLtd => 0x1098,
            Real3D => 0x003d,
            Rendition => 0x1163,
            S3Inc => 0x5333,
            SierraSemiconductor => 0x10a8,
            SiliconIntegratedSystemsSiS => 0x1039,
            SiliconMotionInc => 0x126f,
            STBSystemsInc => 0x10b4,
            TexasInstruments => 0x104c,
            ToshibaAmericaInfoSystems => 0x1179,
            TridentMicrosystems => 0x1023,
            TsengLabsInc => 0x100c,
            TundraSemiconductorCorp => 0x10e3,
            VIATechnologiesInc => 0x1106,
            VirtIO => 0x1AF4,
            VMWareInc => 0x15ad,
            Weitek => 0x100e,
            Unknown(id) => id,
        }
    }
}

impl Display for Vendor {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        use Vendor::*;

        match self {
            Qemu => write!(f, "{}", "\0PINK\0QEMU (0x1234)"),
            VirtIO => write!(f, "{}", "\0PINK\0VirtIO (0x1AF4)"),
            VMWareInc => write!(f, "{}", "\0PINK\0VMWARE (0x15AD)"),
            S3Inc => write!(f, "{}", "\0YELLOW\0S3 Incorporated (0x5333)"),
            IntelCorp => write!(f, "{}", "\0BLUE\0Intel Corp. (0x8086)"),
            ATITechnologiesInc => write!(f, "{}", "\0RED\0ATI (0x1002)"),
            Unknown(id) => write!(f, "\0RED\0Unknown ({:#6})", id),
            other => write!(f, "{other:?}"),
        }?;

        write!(f, "\0RESET\0")?;
        Ok(())
    }
}
