from ctypes import Structure, c_uint32
from enum import IntEnum
from .pdc_dpam_types import DISCCapability, DISCDpSignaling, PinAssignmentModes


class DPAMCommand(IntEnum):
    DoesNothing = 0x00
    AutoEnterDPAM = 0x01
    EnterDPAM2lanes = 0x02
    EnterDPAM4lanes = 0x03
    ExitDPAM = 0x04
    DisableDPAM = 0x05
    ManualDPAM = 0x06
    DisableDPtoTypeCAdapter = 0x08
    EnableDPtoTypeCAdapter = 0x09
    ClearMFPreferredFlag = 0x0E
    SetMFPreferredFlag = 0x0F
    ClearAlignDpCUsb = 0x30
    SetAlignDpCUsb = 0x31
    ClearAlignDpDUsb = 0x32
    SetAlignDpDUsb = 0x33
    ClearAlignDpEUsb = 0x34
    SetAlignDpEUsb = 0x35
    EnableDPAM2_1 = 0x38
    DisableDPAM2_1 = 0x39


class DPAMCaps(Structure):
    _fields_ = [
        ('', c_uint32, 8),
        ('dfp_assign', c_uint32, 8),
        ('ufp_assign', c_uint32, 8),
        ('', c_uint32, 6),
        ('dpam_version', c_uint32, 2)
    ]

    def value(self) -> int:
        return self.dfp_assign << 8 | self.dfp_assign << 16 | self.dpam_version << 30


class DPAMState(Structure):
    _fields_ = [
        ('auto_dpam', c_uint32, 1),
        ('dpam_enable', c_uint32, 1),
        ('adapter_mode', c_uint32, 1),
        ('', c_uint32, 1),
        ('align_dp_c_usb', c_uint32, 1),
        ('align_dp_d_usb', c_uint32, 1),
        ('align_dp_e_usb', c_uint32, 1),
        ('', c_uint32, 25)
    ]


class DPAMConfig(Structure):
    _fields_ = [
        ('config', c_uint32, 2),
        ('signaling', c_uint32, 4),
        ('', c_uint32, 2),
        ('pin_assign', c_uint32, 8),
        ('', c_uint32, 10),
        ('uhbr_13_5_support', c_uint32, 1),
        ('', c_uint32, 1),
        ('cable_active_component', c_uint32, 2),
        ('dpam_version', c_uint32, 2)
    ]


class DPAMDiscModes(Structure):
    _fields_ = [
        ('capability', c_uint32, 2),
        ('signaling', c_uint32, 4),
        ('dp_placement', c_uint32, 1),
        ('usb_signaling', c_uint32, 1),
        ('dfp_assign', c_uint32, 8),
        ('ufp_assign', c_uint32, 8),
        ('', c_uint32, 6),
        ('dpam_version', c_uint32, 2)
    ]

    @property
    def capability(self) -> DISCCapability:
        return DISCCapability(self.capability)

    @property
    def signaling(self) -> DISCDpSignaling:
        return DISCDpSignaling(self.signaling)


class DPAMRecv(Structure):
    _fields_ = [
        ('connection', c_uint32, 2),
        ('power_low', c_uint32, 1),
        ('enable', c_uint32, 1),
        ('multi_func', c_uint32, 1),
        ('usb_cfg_rq', c_uint32, 1),
        ('exit_rq', c_uint32, 1),
        ('hpd_state', c_uint32, 1),
        ('hpd_irq', c_uint32, 1),
        ('no_dpam_suspend', c_uint32, 1),
    ]

    @property
    def connection(self) -> DISCCapability:
        return DISCCapability(self.capability)
