from ctypes import Structure, c_uint32


class DPTXHWCaps(Structure):
    _fields_ = [
        ('mst', c_uint32, 1),
        ('hdcp_1_x', c_uint32, 1),
        ('hdcp_2_x', c_uint32, 1),
        ('fec', c_uint32, 1),
        ('dsc', c_uint32, 1),
        ('alpm', c_uint32, 1),
        ('lane_3', c_uint32, 1),
        ('edp', c_uint32, 1),
        ('mst_stream_count', c_uint32, 4),
        ('', c_uint32, 4),
        ('max_link_rate', c_uint32, 8),
        ('', c_uint32, 1),
        ('dp2_custom_rates', c_uint32, 1),
        ('custom_rates_ext', c_uint32, 1),
        ('adaptive_sync', c_uint32, 1),
        ('edid_parser', c_uint32, 1),
        ('', c_uint32, 1),
        ('fec2', c_uint32, 1),
        ('dsc2', c_uint32, 1),
        ('support_10gbps', c_uint32, 1),
        ('support_20gbps', c_uint32, 1),
        ('support_13_5gbps', c_uint32, 1),
        ('', c_uint32, 29),
        ('link_pat_log', c_uint32, 1),
        ('vbid_hw_log', c_uint32, 1),
        ('msa_hw_log', c_uint32, 1),
        ('aux_bw_log', c_uint32, 1),
        ('', c_uint32, 28),
        ('scrambler_seed', c_uint32, 1),
        ('dp2_sdp_crc', c_uint32, 1),
        ('sdp_split', c_uint32, 1),
        ('dp2_sdp_split', c_uint32, 1),
        ('', c_uint32, 28),
        ('supported_dp2_custom_rates', c_uint32 * 32),
    ]


class LTFeatures(Structure):
    _fields_ = [
        ('skew', c_uint32, 1),
        ('', c_uint32, 1),
        ('framing', c_uint32, 1),
        ('try_3_lane', c_uint32, 1),
        ('try_edp', c_uint32, 1),
        ('force_edp', c_uint32, 1),
        ('try_dp2', c_uint32, 1),
        ('force_dp2', c_uint32, 1),
        ('old_dp2_lt', c_uint32, 1),
        ('auto_seed', c_uint32, 1),
        ('max_link_bw_policy', c_uint32, 1),
        ('edp_aux_preamble', c_uint32, 1)
    ]

    def value(self) -> int:
        return self.framing << 2 | self.try_edp << 4 | self.force_edp << 5 | self.try_dp2 << 6 | self.force_dp2 << 7 |\
               self.old_dp2_lt << 8 | self.auto_seed << 9 | self.max_link_bw_policy << 10 | self.edp_aux_preamble << 11


class LinkTxStatus(Structure):
    _fields_ = [
        ('l0_cr', c_uint32, 1),
        ('l0_eq', c_uint32, 1),
        ('l0_sl', c_uint32, 1),
        ('', c_uint32, 1),
        ('l1_cr', c_uint32, 1),
        ('l1_eq', c_uint32, 1),
        ('l1_sl', c_uint32, 1),
        ('', c_uint32, 1),
        ('l2_cr', c_uint32, 1),
        ('l2_eq', c_uint32, 1),
        ('l2_sl', c_uint32, 1),
        ('', c_uint32, 1),
        ('l3_cr', c_uint32, 1),
        ('l3_eq', c_uint32, 1),
        ('l3_sl', c_uint32, 1),
        ('', c_uint32, 13),
        ('lt_fail', c_uint32, 1),
        ('cds_ila', c_uint32, 1),
        ('eq_ila', c_uint32, 1),
        ('ila', c_uint32, 1)
    ]


class PostLtFeatures(Structure):
    _fields_ = [
        ('force_edid_timings', c_uint32, 1),
        ('as_auto_enable', c_uint32, 1)
    ]

    def value(self) -> int:
        return self.force_edid_timings | self.as_auto_enable << 1


class SdpControl(Structure):
    _fields_ = [
        ('dp2_crc_sdp', c_uint32, 1),
        ('dp_split_sdp', c_uint32, 1),
        ('dp2_split_sdp', c_uint32, 1)
    ]

    def value(self) -> int:
        return self.dp2_crc_sdp | self.dp_split_sdp << 1
