from enum import IntEnum
from UniTAP.dev.modules.dut_tests.test_group_params_types import Param
from UniTAP.dev.modules.dut_tests.test_utils import CMTFormat, CMTVSCFormat, CMTBitDepth, CMTVSCBitDepth,\
    make_cf, make_vsc_cf, update_default_value


class EventIndication(IntEnum):
    """
    Describes available events indications for test automation.
    """
    Unknown = -1
    AlwaysReady = 0
    EdidRead = 1
    LinkTrainingEnd = 2
    ActiveVideo = 3


class MaxSupportedVideoMode(IntEnum):
    """
    Describes available video modes for field `max_supported_video_mode`.
    """
    T_640x480_60Hz_6BPC = 1
    T_848x480_60Hz_8BPC = 2
    T_1280x720_60Hz_8BPC = 3
    T_1280x960_60Hz_8BPC = 4
    T_1920x1080_60Hz_8BPC = 5
    T_1920x1440_60Hz_8BPC = 6
    T_1920x1080_120Hz_8BPC = 7
    T_1280x800_60Hz_RB1_6BPC = 8
    T_1280x768_60Hz_RB1_6BPC = 9
    T_800x600_60Hz_10BPC = 10
    T_1024x768_60Hz_10BPC = 11
    T_1280x1024_60Hz_8BPC = 12
    T_1360x768_60Hz_10BPC = 13
    T_1280x800_60Hz_RB1_10BPC = 14
    T_1400x1050_60Hz_RB1_8BPC = 15
    T_1280x768_60Hz_RB1_10BPC = 16
    T_1600x1200_60Hz_RB1_6BPC = 17
    T_2048x1536_60Hz_RB1_8BPC = 18
    T_1792x1344_60Hz_8BPC = 19
    T_1600x1200_60Hz_RB1_10BPC = 20
    T_3840x2160_30Hz_8BPC = 21
    T_3840x2160_60Hz_8BPC = 22


class PackedTimings1Lane(IntEnum):
    """
    Describes available timings for field `packed_timings_1_lane`.
    """
    NoneTiming = 0
    DMT_800x600_60Hz_10BPC = 10
    DMT_1024x768_60Hz_6BPC = 11
    CVT_1280x800_60Hz_RB1_6BPC = 8
    DMT_1280x768_60Hz_RB1_6BPC = 9
    CTA_1440x480_60Hz_8BPC = 23
    CTA_1440x576_50Hz_8BPC = 24


class PackedTimings2Lane(IntEnum):
    """
    Describes available timings for field `packed_timings_2_lane`.
    """
    NoneTiming = 0
    DMT_1280x768_60Hz_10BPC = 16
    CVT_1280x800_60Hz_10BPC = 14
    DMT_1280x960_60Hz_8BPC = 4
    DMT_1280x1024_60Hz_8BPC = 12
    DMT_1360x768_60Hz_10BPC = 13
    DMT_1400x1050_60Hz_RB1_8BPC = 15
    CVT_1600x1200_60Hz_RB1_6BPC = 17
    DMT_1360x768_60Hz_8BPC = 13
    CVT_1280x800_60Hz_8BPC = 26
    DMT_1280x768_60Hz_8BPC = 25


class PackedTimings4Lane(IntEnum):
    """
    Describes available timings for field `packed_timings_4_lane`.
    """
    NoneTiming = 0
    DMT_1600x1200_60Hz_10BPC = 20
    DMT_1600x1200_60Hz_8BPC = 28
    DMT_1792x1344_60Hz_8BPC = 19
    CTA_1920x1080_60Hz_10BPC = 29
    CTA_1920x1080_60Hz_8BPC = 5
    CVT_2048x1536_60Hz_RB1_8BPC = 18


class Rbb1Lane(IntEnum):
    """
    Describes available timings for field `rbb_1l`.
    """
    NoneTiming = 0
    T_640x480_60Hz_6BPC = 1
    T_848x480_60Hz_8BPC = 2


class Rbb2Lane(IntEnum):
    """
    Describes available timings for field `rbb_2l`.
    """
    NoneTiming = 0
    T_640x480_60Hz_6BPC = 1
    T_848x480_60Hz_8BPC = 2
    T_1280x720_60Hz_8BPC = 3


class Rbb4Lane(IntEnum):
    """
    Describes available timings for field `rbb_4l`.
    """
    NoneTiming = 0
    T_640x480_60Hz_6BPC = 1
    T_848x480_60Hz_8BPC = 2
    T_1280x720_60Hz_8BPC = 3
    T_1280x960_60Hz_8BPC = 4
    T_1920_1080_60Hz_8BPC = 5


class Hbr1Lane(IntEnum):
    """
    Describes available timings for field `hbr_1l`.
    """
    NoneTiming = 0
    T_640x480_60Hz_6BPC = 1
    T_848x480_60Hz_8BPC = 2
    T_1280x720_60Hz_8BPC = 3


class Hbr2Lane(IntEnum):
    """
    Describes available timings for field `hbr_2l`.
    """
    NoneTiming = 0
    T_640x480_60Hz_6BPC = 1
    T_848x480_60Hz_8BPC = 2
    T_1280x720_60Hz_8BPC = 3
    T_1280x960_60Hz_8BPC = 4


class Hbr4Lane(IntEnum):
    """
    Describes available timings for field `hbr_4l`.
    """
    NoneTiming = 0
    T_640x480_60Hz_6BPC = 1
    T_848x480_60Hz_8BPC = 2
    T_1280x720_60Hz_8BPC = 3
    T_1280x960_60Hz_8BPC = 4
    T_1920_1080_60Hz_8BPC = 5
    T_1920_1440_60Hz_8BPC = 6


class Hbr2_1Lane(IntEnum):
    """
    Describes available timings for field `hbr2_1l`.
    """
    NoneTiming = 0
    T_640x480_60Hz_6BPC = 1
    T_848x480_60Hz_8BPC = 2
    T_1280x720_60Hz_8BPC = 3
    T_1280x960_60Hz_8BPC = 4


class Hbr2_2Lane(IntEnum):
    """
    Describes available timings for field `hbr2_2l`.
    """
    NoneTiming = 0
    T_640x480_60Hz_6BPC = 1
    T_848x480_60Hz_8BPC = 2
    T_1280x720_60Hz_8BPC = 3
    T_1280x960_60Hz_8BPC = 4
    T_1920_1080_60Hz_8BPC = 5
    T_1920_1440_60Hz_8BPC = 6


class Hbr2_4Lane(IntEnum):
    """
    Describes available timings for field `hbr2_4l`.
    """
    NoneTiming = 0
    T_640x480_60Hz_6BPC = 1
    T_848x480_60Hz_8BPC = 2
    T_1280x720_60Hz_8BPC = 3
    T_1280x960_60Hz_8BPC = 4
    T_1920_1080_60Hz_8BPC = 5
    T_1920_1440_60Hz_8BPC = 6
    T_1920x1080_120Hz_8BPC = 7


class Hbr3_1Lane(IntEnum):
    """
    Describes available timings for field `hbr3_1l`.
    """
    NoneTiming = 0
    T_640x480_60Hz_6BPC = 1
    T_848x480_60Hz_8BPC = 2
    T_1280x720_60Hz_8BPC = 3
    T_1280x960_60Hz_8BPC = 4
    T_1920_1080_60Hz_8BPC = 5
    T_1920_1440_60Hz_8BPC = 6


class Hbr3_2Lane(IntEnum):
    """
    Describes available timings for field `hbr3_2l`.
    """
    NoneTiming = 0
    T_640x480_60Hz_6BPC = 1
    T_848x480_60Hz_8BPC = 2
    T_1280x720_60Hz_8BPC = 3
    T_1280x960_60Hz_8BPC = 4
    T_1920_1080_60Hz_8BPC = 5
    T_1920_1440_60Hz_8BPC = 6
    T_1920x1080_120Hz_8BPC = 7
    T_1280x800_60Hz_RB1_6BPC = 8
    T_1280x768_60Hz_RB1_6BPC = 9
    T_800x600_60Hz_10BPC = 10
    T_1024x768_60Hz_10BPC = 11
    T_1280x1024_60Hz_8BPC = 12
    T_1360x768_60Hz_10BPC = 13
    T_1280x800_60Hz_RB1_10BPC = 14
    T_1400x1050_60Hz_RB1_8BPC = 15
    T_1280x768_60Hz_RB1_10BPC = 16
    T_1600x1200_60Hz_RB1_6BPC = 17
    T_2048x1536_60Hz_RB1_8BPC = 18
    T_1792x1344_60Hz_8BPC = 19
    T_1600x1200_60Hz_RB1_10BPC = 20
    T_3840x2160_30Hz_8BPC = 21


class Hbr3_4Lane(IntEnum):
    """
    Describes available timings for field `hbr3_4l`.
    """
    NoneTiming = 0
    T_640x480_60Hz_6BPC = 1
    T_848x480_60Hz_8BPC = 2
    T_1280x720_60Hz_8BPC = 3
    T_1280x960_60Hz_8BPC = 4
    T_1920_1080_60Hz_8BPC = 5
    T_1920_1440_60Hz_8BPC = 6
    T_1920x1080_120Hz_8BPC = 7
    T_1280x800_60Hz_RB1_6BPC = 8
    T_1280x768_60Hz_RB1_6BPC = 9
    T_800x600_60Hz_10BPC = 10
    T_1024x768_60Hz_10BPC = 11
    T_1280x1024_60Hz_8BPC = 12
    T_1360x768_60Hz_10BPC = 13
    T_1280x800_60Hz_RB1_10BPC = 14
    T_1400x1050_60Hz_RB1_8BPC = 15
    T_1280x768_60Hz_RB1_10BPC = 16
    T_1600x1200_60Hz_RB1_6BPC = 17
    T_2048x1536_60Hz_RB1_8BPC = 18
    T_1792x1344_60Hz_8BPC = 19
    T_1600x1200_60Hz_RB1_10BPC = 20
    T_3840x2160_30Hz_8BPC = 21
    T_3840x2160_60Hz_8BPC = 22


class TestAutomationFlags:
    """
    Class `TestAutomationFlags` allows configuring test automation flags:
    - Set and get Test link training flag `test_link_training`.
    - Set and get Test EDID read flag `test_edid_read`.
    - Set and get Test video pattern flag `test_video_pattern`.
    - Set and get Test audio pattern flag `test_audio_pattern`.
    - Set and get Test Event indication `event_indication` type `EventIndication`.
    """
    def __init__(self, json_obj):
        self._param = Param(json_obj)

    @property
    def test_link_training(self) -> bool:
        """
        Set and get link training flag.

        Returns:
            object of bool type
        """
        return self._param._get_by_bitmask(0, bool)

    @test_link_training.setter
    def test_link_training(self, test_link_training: bool):
        self._param._set_by_bitmask(int(test_link_training), 0)

    @property
    def test_edid_read(self) -> bool:
        """
        Set and get EDID read flag.

        Returns:
            object of bool type
        """
        return self._param._get_by_bitmask(1, bool)

    @test_edid_read.setter
    def test_edid_read(self, test_edid_read: bool):
        self._param._set_by_bitmask(int(test_edid_read), 1)

    @property
    def test_video_pattern(self) -> bool:
        """
        Set and get video pattern flag.

        Returns:
            object of bool type
        """
        return self._param._get_by_bitmask(2, bool)

    @test_video_pattern.setter
    def test_video_pattern(self, test_video_pattern: bool):
        self._param._set_by_bitmask(int(test_video_pattern), 2)

    @property
    def test_audio_pattern(self) -> bool:
        """
        Set and get audio pattern flag.

        Returns:
            object of bool type
        """
        return self._param._get_by_bitmask(3, bool)

    @test_audio_pattern.setter
    def test_audio_pattern(self, test_audio_pattern: bool):
        self._param._set_by_bitmask(int(test_audio_pattern), 3)

    @property
    def event_indication(self) -> EventIndication:
        """
        Set and get link training flag.

        Returns:
            object of `EventIndication` type
        """
        return self._param._get_by_bitmask(4, EventIndication)

    @event_indication.setter
    def event_indication(self, event_indication: EventIndication):
        self._param._set_by_bitmask(event_indication.value, 4)


class DutCapsFlags(Param):
    """
    Class `DutCapsFlags` defines the DUT capabilities as flags and allows setting:
    - Voltage swing level 3 (1.2V) supported `voltage_swing_supported`.
    - Pre-emphasis level 3 (9.5dB) supported `pre_emphasis_supported`.
    - Fixed timing DUT supported `fixed_timing_dut_supported`.
    - Spread Spectrum supported `spread_spectrum_supported`.
    - Video format change without LT supported `change_vf_without_lt_supported`.
    - Lane count reduction without LT supported `lane_count_reduction_without_lt_supported`.
    - E-DDC protocol supported `e_ddc_protocol_supported`.
    - Audio Info Frame for 2 channel audio transmission supported `audio_transmission_supported`.
    - Define that DUT is Type-C device `dut_is_type_c_device`.
    - FEC supported `fec_supported`.
    - FEC disable sequence supported `fec_disable_sequence_supported`.
    - Audio without Video supported `audio_without_video_supported`.
    - DSC supported `dsc_supported`.
    - DSC block prediction supported `dsc_block_prediction_supported`.
    - DisplayID Type VII Detailed Timing Descriptor supported `display_id_vii_supported`.
    - DisplayID Type VIII Detailed Timing Descriptor supported `display_id_viii_supported`.
    - DisplayID Type IX Detailed Timing Descriptor supported `display_id_ix_supported`.
    - DisplayID Type X Detailed Timing Descriptor supported `display_id_x_supported`.
    - 2x1 tiled display and DisplayID Tiled Display Topology data block supported `display_id_tiled_display_topology`.
    - Field sequential stereo and DisplayID Tiled Stereo Display Interface data block supported
    `display_id_tiled_stereo_display`
    - Stacked frame stereo and DisplayID Tiled Stereo Display Interface data block supported
    `stacked_frame_stereo_supported`.
    """
    def __init__(self, json_obj):
        super().__init__(json_obj)

    @property
    def voltage_swing_supported(self) -> bool:
        """
        Set and get Voltage swing level flag support.

        Returns:
            object of bool type
        """
        return self._get_by_bitmask(0, bool)

    @voltage_swing_supported.setter
    def voltage_swing_supported(self, voltage_swing_supported: bool):
        self._set_by_bitmask(voltage_swing_supported, 0)


    @property
    def pre_emphasis_supported(self) -> bool:
        """
        Set and get Pre-emphasis level flag support.

        Returns:
            object of bool type
        """
        return self._get_by_bitmask(1, bool)

    @pre_emphasis_supported.setter
    def pre_emphasis_supported(self, pre_emphasis_supported: bool):
        self._set_by_bitmask(pre_emphasis_supported, 1)

    @property
    def fixed_timing_dut_supported(self) -> bool:
        """
        Set and get Fixed timing DUT flag support.

        Returns:
            object of bool type
        """
        return self._get_by_bitmask(2, bool)

    @fixed_timing_dut_supported.setter
    def fixed_timing_dut_supported(self, fixed_timing_dut_supported: bool):
        self._set_by_bitmask(fixed_timing_dut_supported, 2)

    @property
    def spread_spectrum_supported(self) -> bool:
        """
        Set and get Spread Spectrum flag support.

        Returns:
            object of bool type
        """
        return self._get_by_bitmask(3, bool)

    @spread_spectrum_supported.setter
    def spread_spectrum_supported(self, spread_spectrum_supported: bool):
        self._set_by_bitmask(spread_spectrum_supported, 3)

    @property
    def change_vf_without_lt_supported(self) -> bool:
        """
        Set and get Video format change without LT flag support.

        Returns:
            object of bool type
        """
        return self._get_by_bitmask(4, bool)

    @change_vf_without_lt_supported.setter
    def change_vf_without_lt_supported(self, change_vf_without_lt_supported: bool):
        self._set_by_bitmask(change_vf_without_lt_supported, 4)

    @property
    def lane_count_reduction_without_lt_supported(self) -> bool:
        """
        Set and get Lane count reduction without LT flag support.

        Returns:
            object of bool type
        """
        return self._get_by_bitmask(5, bool)

    @lane_count_reduction_without_lt_supported.setter
    def lane_count_reduction_without_lt_supported(self, lane_count_reduction_without_lt_supported: bool):
        self._set_by_bitmask(lane_count_reduction_without_lt_supported, 5)

    @property
    def e_ddc_protocol_supported(self) -> bool:
        """
        Set and get E-DDC protocol flag support.

        Returns:
            object of bool type
        """
        return self._get_by_bitmask(6, bool)

    @e_ddc_protocol_supported.setter
    def e_ddc_protocol_supported(self, e_ddc_protocol_supported: bool):
        self._set_by_bitmask(e_ddc_protocol_supported, 6)

    @property
    def audio_transmission_supported(self) -> bool:
        """
        Set and get Audio Info Frame for 2 channel audio transmission flag support.

        Returns:
            object of bool type
        """
        return self._get_by_bitmask(7, bool)

    @audio_transmission_supported.setter
    def audio_transmission_supported(self, audio_transmission_supported: bool):
        self._set_by_bitmask(audio_transmission_supported, 7)

    @property
    def dut_is_type_c_device(self) -> bool:
        """
        Set and get Define that DUT is Type-C device flag support.

        Returns:
            object of bool type
        """
        return self._get_by_bitmask(8, bool)

    @dut_is_type_c_device.setter
    def dut_is_type_c_device(self, dut_is_type_c_device: bool):
        self._set_by_bitmask(dut_is_type_c_device, 8)

    @property
    def fec_supported(self) -> bool:
        """
        Set and get FEC flag support.

        Returns:
            object of bool type
        """
        return self._get_by_bitmask(9, bool)

    @fec_supported.setter
    def fec_supported(self, fec_supported: bool):
        self._set_by_bitmask(fec_supported, 9)

    @property
    def fec_disable_sequence_supported(self) -> bool:
        """
        Set and get FEC disable sequence flag support.

        Returns:
            object of bool type
        """
        return self._get_by_bitmask(10, bool)

    @fec_disable_sequence_supported.setter
    def fec_disable_sequence_supported(self, fec_disable_sequence_supported: bool):
        self._set_by_bitmask(fec_disable_sequence_supported, 10)

    @property
    def audio_without_video_supported(self) -> bool:
        """
        Set and get Audio without Video flag support.

        Returns:
            object of bool type
        """
        return self._get_by_bitmask(11, bool)

    @audio_without_video_supported.setter
    def audio_without_video_supported(self, audio_without_video_supported: bool):
        self._set_by_bitmask(audio_without_video_supported, 11)

    @property
    def dsc_supported(self) -> bool:
        """
        Set and get DSC flag support.

        Returns:
            object of bool type
        """
        return self._get_by_bitmask(12, bool)

    @dsc_supported.setter
    def dsc_supported(self, dsc_supported: bool):
        self._set_by_bitmask(dsc_supported, 12)

    @property
    def dsc_block_prediction_supported(self) -> bool:
        """
        Set and get DSC block prediction flag support.

        Returns:
            object of bool type
        """
        return self._get_by_bitmask(13, bool)

    @dsc_block_prediction_supported.setter
    def dsc_block_prediction_supported(self, dsc_block_prediction_supported: bool):
        self._set_by_bitmask(dsc_block_prediction_supported, 13)

    @property
    def native_display_id_read(self) -> bool:
        """
        Set and get DUT supports native Display ID read flag support.

        Returns:
            object of bool type
        """
        return self._get_by_bitmask(14, bool)

    @native_display_id_read.setter
    def native_display_id_read(self, native_display_id_read: bool):
        self._set_by_bitmask(native_display_id_read, 14)

    @property
    def display_id_vii_supported(self) -> bool:
        """
        Set and get DisplayID Type VII Detailed Timing Descriptor flag support.

        Returns:
            object of bool type
        """
        return self._get_by_bitmask(15, bool)

    @display_id_vii_supported.setter
    def display_id_vii_supported(self, display_id_vii_supported: bool):
        self._set_by_bitmask(display_id_vii_supported, 15)

    @property
    def display_id_viii_supported(self) -> bool:
        """
        Set and get DisplayID Type VIII Detailed Timing Descriptor flag support.

        Returns:
            object of bool type
        """
        return self._get_by_bitmask(16, bool)

    @display_id_viii_supported.setter
    def display_id_viii_supported(self, display_id_viii_supported: bool):
        self._set_by_bitmask(display_id_viii_supported, 16)

    @property
    def display_id_ix_supported(self) -> bool:
        """
        Set and get DisplayID Type IX Detailed Timing Descriptor flag support.

        Returns:
            object of bool type
        """
        return self._get_by_bitmask(17, bool)

    @display_id_ix_supported.setter
    def display_id_ix_supported(self, display_id_ix_supported: bool):
        self._set_by_bitmask(display_id_ix_supported, 17)

    @property
    def display_id_x_supported(self) -> bool:
        """
        Set and get DisplayID Type X Detailed Timing Descriptor flag support.

        Returns:
            object of bool type
        """
        return self._get_by_bitmask(18, bool)

    @display_id_x_supported.setter
    def display_id_x_supported(self, display_id_x_supported: bool):
        self._set_by_bitmask(display_id_x_supported, 18)

    @property
    def display_id_tiled_display_topology(self) -> bool:
        """
        Set and get 2x1 tiled display and DisplayID Tiled Display Topology data block flag support.

        Returns:
            object of bool type
        """
        return self._get_by_bitmask(19, bool)

    @display_id_tiled_display_topology.setter
    def display_id_tiled_display_topology(self, display_id_tiled_display_topology: bool):
        self._set_by_bitmask(display_id_tiled_display_topology, 19)

    @property
    def display_id_tiled_stereo_display(self) -> bool:
        """
        Set and get Field sequential stereo and DisplayID Tiled Stereo Display Interface data block flag support.

        Returns:
            object of bool type
        """
        return self._get_by_bitmask(20, bool)

    @display_id_tiled_stereo_display.setter
    def display_id_tiled_stereo_display(self, display_id_tiled_stereo_display: bool):
        self._set_by_bitmask(display_id_tiled_stereo_display, 20)

    @property
    def stacked_frame_stereo_supported(self) -> bool:
        """
        Set and get Stacked frame stereo and DisplayID Tiled Stereo Display Interface data flag support.

        Returns:
            object of bool type
        """
        return self._get_by_bitmask(21, bool)

    @stacked_frame_stereo_supported.setter
    def stacked_frame_stereo_supported(self, stacked_frame_stereo_supported: bool):
        self._set_by_bitmask(stacked_frame_stereo_supported, 21)

    def clear_all_caps(self):
        """
        Clear all settings.
        """
        self.voltage_swing_supported = False
        self.pre_emphasis_supported = False
        self.fixed_timing_dut_supported = False
        self.spread_spectrum_supported = False
        self.change_vf_without_lt_supported = False
        self.lane_count_reduction_without_lt_supported = False
        self.e_ddc_protocol_supported = False
        self.audio_transmission_supported = False
        self.dut_is_type_c_device = False
        self.fec_supported = False
        self.fec_disable_sequence_supported = False
        self.audio_without_video_supported = False
        self.dsc_supported = False
        self.dsc_block_prediction_supported = False
        self.native_display_id_read = False
        self.display_id_vii_supported = False
        self.display_id_viii_supported = False
        self.display_id_ix_supported = False
        self.display_id_x_supported = False
        self.display_id_tiled_display_topology = False
        self.display_id_tiled_stereo_display = False
        self.stacked_frame_stereo_supported = False


class DutCapsDp14:
    """
    Class `DutCapsDp14` defines the DUT capabilities and allows setting:
    - Defines the maximum number of lanes supported by the DUT `max_lanes`.
    - Maximum link rate supported by the DUT `max_link_rate`.
    - Dut capabilities flags `dut_caps_flags` type `DutCapsFlags`.
    """
    def __init__(self, json_obj):
        self.__max_lanes = Param(json_obj["TSI_DP14_SRCCTS_MAX_LANES"])
        self.__max_link_rate = Param(json_obj["TSI_DP14_SRCCTS_MAX_LINK_RATE"])
        self.__dut_caps_flags = DutCapsFlags(json_obj["TSI_DP14_SRCCTS_DUT_CAPS"])

    @property
    def max_lanes(self) -> int:
        """
        Set and get number of maximum lanes.

        Returns:
            object of int type
        """
        return self.__max_lanes.default_value

    @max_lanes.setter
    def max_lanes(self, max_lanes: int):
        if max_lanes not in [1, 2, 4]:
            raise ValueError(f"Max lane count must be from list: 1, 2, 4. Current value: {max_lanes}")
        self.__max_lanes.default_value = max_lanes

    @property
    def max_link_rate(self):
        """
        Set and get number of maximum link rate.

        Returns:
            object of int type
        """
        return self.__max_link_rate

    @max_link_rate.setter
    def max_link_rate(self, max_link_rate: float):
        if max_link_rate not in [1.62, 2.7, 5.4, 8.1]:
            raise ValueError(f"Max link rate must be from list: 1.62, 2.7, 5.4, 8.1. Current value: {max_link_rate}")
        self.__max_link_rate.default_value = round(max_link_rate / 0.27)

    @property
    def dut_caps_flags(self) -> DutCapsFlags:
        """
        Set and get DUT capabilities flags.

        Returns:
            object of `DutCapsFlags` type
        """
        return self.__dut_caps_flags

    @dut_caps_flags.setter
    def dut_caps_flags(self, dut_caps_flags: DutCapsFlags):
        self.__dut_caps_flags = dut_caps_flags


class TimeStampGenerationDp14:
    """
    Class `TimeStampGenerationDp14` defines timings which used for different rates and allows setting:
    - Video timings used for Reduced Bitrate (RBR, 1.62Gbps) testing for 1 lanes `rbb_1l`.
    - Video timings used for Reduced Bitrate (RBR, 1.62Gbps) testing for 2 lanes `rbb_2l`.
    - Video timings used for Reduced Bitrate (RBR, 1.62Gbps) testing for 4 lanes `rbb_4l`.
    - Video timings used for High Bitrate (HBR, 2.7Gbps) testing for 1 lanes `hbr_1l`.
    - Video timings used for High Bitrate (HBR, 2.7Gbps) testing for 2 lanes `hbr_2l`.
    - Video timings used for High Bitrate (HBR, 2.7Gbps) testing for 4 lanes `hbr_4l`.
    - Video timings used for High Bitrate-2 (HBR2, 5.4Gbps) testing for 1 lane `hbr2_1l`.
    - Video timings used for High Bitrate-2 (HBR2, 5.4Gbps) testing for 2 lane `hbr2_2l`.
    - Video timings used for High Bitrate-2 (HBR2, 5.4Gbps) testing for 4 lane `hbr2_4l`.
    - Video timings used for High Bitrate-3 (HBR3, 8.1Gbps) testing for 1 lanes `hbr3_1l`.
    - Video timings used for High Bitrate-3 (HBR3, 8.1Gbps) testing for 2 lanes `hbr3_2l`.
    - Video timings used for High Bitrate-3 (HBR3, 8.1Gbps) testing for 4 lanes `hbr3_4l`.
    """
    def __init__(self, json_obj):
        self.__rbb_1l = Param(json_obj["TSI_DP14_SRCCTS_1L_RBB"])
        self.__rbb_2l = Param(json_obj["TSI_DP14_SRCCTS_2L_RBB"])
        self.__rbb_4l = Param(json_obj["TSI_DP14_SRCCTS_4L_RBB"])

        self.__hbr_1l = Param(json_obj["TSI_DP14_SRCCTS_1L_HBR"])
        self.__hbr_2l = Param(json_obj["TSI_DP14_SRCCTS_2L_HBR"])
        self.__hbr_4l = Param(json_obj["TSI_DP14_SRCCTS_4L_HBR"])

        self.__hbr2_1l = Param(json_obj["TSI_DP14_SRCCTS_1L_HBR2"])
        self.__hbr2_2l = Param(json_obj["TSI_DP14_SRCCTS_2L_HBR2"])
        self.__hbr2_4l = Param(json_obj["TSI_DP14_SRCCTS_4L_HBR2"])

        self.__hbr3_1l = Param(json_obj["TSI_DP14_SRCCTS_1L_HBR3"])
        self.__hbr3_2l = Param(json_obj["TSI_DP14_SRCCTS_2L_HBR3"])
        self.__hbr3_4l = Param(json_obj["TSI_DP14_SRCCTS_4L_HBR3"])

    @property
    def rbb_1l(self):
        """
        Set and get Video timings used for Reduced Bitrate (RBR, 1.62Gbps) testing for 1 lanes.

        Returns:
            object of `Rbb1Lane` type
        """
        return self.__rbb_1l

    @rbb_1l.setter
    def rbb_1l(self, rbb_1l: Rbb1Lane):
        self.__rbb_1l.default_value = rbb_1l.value

    @property
    def rbb_2l(self):
        """
        Set and get Video timings used for Reduced Bitrate (RBR, 1.62Gbps) testing for 2 lanes.

        Returns:
            object of `Rbb2Lane` type
        """
        return self.__rbb_2l

    @rbb_2l.setter
    def rbb_2l(self, rbb_2l: Rbb2Lane):
        self.__rbb_2l.default_value = rbb_2l.value

    @property
    def rbb_4l(self):
        """
        Set and get Video timings used for Reduced Bitrate (RBR, 1.62Gbps) testing for 4 lanes.

        Returns:
            object of `Rbb4Lane` type
        """
        return self.__rbb_4l

    @rbb_4l.setter
    def rbb_4l(self, rbb_4l: Rbb4Lane):
        self.__rbb_4l.default_value = rbb_4l.value

    @property
    def hbr_1l(self):
        """
        Set and get Video timings used for High Bitrate (HBR, 2.7Gbps) testing for 1 lanes.

        Returns:
            object of `Hbr1Lane` type
        """
        return self.__hbr_1l

    @hbr_1l.setter
    def hbr_1l(self, hbr_1l: Hbr1Lane):
        self.__hbr_1l.default_value = hbr_1l.value

    @property
    def hbr_2l(self):
        """
        Set and get Video timings used for High Bitrate (HBR, 2.7Gbps) testing for 2 lanes.

        Returns:
            object of `Hbr2Lane` type
        """
        return self.__hbr_2l

    @hbr_2l.setter
    def hbr_2l(self, hbr_2l: Hbr2Lane):
        self.__hbr_2l.default_value = hbr_2l.value

    @property
    def hbr_4l(self):
        """
        Set and get Video timings used for High Bitrate (HBR, 2.7Gbps) testing for 4 lanes.

        Returns:
            object of `Hbr4Lane` type
        """
        return self.__hbr_4l

    @hbr_4l.setter
    def hbr_4l(self, hbr_4l: Hbr4Lane):
        self.__hbr_4l.default_value = hbr_4l.value

    @property
    def hbr2_1l(self):
        """
        Set and get Video timings used for High Bitrate-2 (HBR2, 5.4Gbps) testing for 1 lane.

        Returns:
            object of `Hbr2_1Lane` type
        """
        return self.__hbr2_1l

    @hbr2_1l.setter
    def hbr2_1l(self, hbr2_1l: Hbr2_1Lane):
        self.__hbr2_1l.default_value = hbr2_1l.value

    @property
    def hbr2_2l(self):
        """
        Set and get Video timings used for High Bitrate-2 (HBR2, 5.4Gbps) testing for 2 lane.

        Returns:
            object of `Hbr2_2Lane` type
        """
        return self.__hbr2_2l

    @hbr2_2l.setter
    def hbr2_2l(self, hbr2_2l: Hbr2_2Lane):
        self.__hbr2_2l.default_value = hbr2_2l.value

    @property
    def hbr2_4l(self):
        """
        Set and get Video timings used for High Bitrate-2 (HBR2, 5.4Gbps) testing for 4 lane.

        Returns:
            object of `Hbr2_4Lane` type
        """
        return self.__hbr2_4l

    @hbr2_4l.setter
    def hbr2_4l(self, hbr2_4l: Hbr2_4Lane):
        self.__hbr2_4l.default_value = hbr2_4l.value

    @property
    def hbr3_1l(self):
        """
        Set and get Video timings used for High Bitrate-3 (HBR3, 8.1Gbps) testing for 1 lanes.

        Returns:
            object of `Hbr3_1Lane` type
        """
        return self.__hbr3_1l

    @hbr3_1l.setter
    def hbr3_1l(self, hbr3_1l: Hbr3_1Lane):
        self.__hbr3_1l.default_value = hbr3_1l.value

    @property
    def hbr3_2l(self):
        """
        Set and get Video timings used for High Bitrate-3 (HBR3, 8.1Gbps) testing for 2 lanes.

        Returns:
            object of `Hbr3_2Lane` type
        """
        return self.__hbr3_2l

    @hbr3_2l.setter
    def hbr3_2l(self, hbr3_2l: Hbr3_2Lane):
        self.__hbr3_2l.default_value = hbr3_2l.value

    @property
    def hbr3_4l(self):
        """
        Set and get Video timings used for High Bitrate-3 (HBR3, 8.1Gbps) testing for 4 lanes.

        Returns:
            object of `Hbr3_4Lane` type
        """
        return self.__hbr3_4l

    @hbr3_4l.setter
    def hbr3_4l(self, hbr3_4l: Hbr3_4Lane):
        self.__hbr3_4l.default_value = hbr3_4l.value


class ColorimetryDp14:
    """
    Class `ColorimetryDp14` describes optional and additional color modes to be used with DP CTS tests.
    - RGB 6 bpc VESA and RGB 8 bpc VESA - Mandatory.
    - RGB 10 bpc VESA `rgb_10bpc_vesa`.
    - RGB 8 bpc CTA `rgb_8bpc_cta`.
    - RGB 10 bpc CTA `rgb_10bpc_cta`.
    - YCbCr-422 8 bpc CTA ITU-601 `ycbcr422_8bpc_cta_itu601`.
    - YCbCr-422 10 bpc CTA ITU-601 `ycbcr422_10bpc_cta_itu601`.
    - YCbCr-422 8 bpc CTA ITU-709 `ycbcr422_8bpc_cta_itu709`.
    - YCbCr-422 10 bpc CTA ITU-709 `ycbcr422_10bpc_cta_itu709`.
    - YCbCr-420 8 bpc CTA ITU-601 `ycbcr420_8bpc_cta_itu601`.
    - YCbCr-420 10 bpc CTA ITU-601 `ycbcr420_10bpc_cta_itu601`.
    - YCbCr-420 8 bpc CTA ITU-709 `ycbcr420_8bpc_cta_itu709`.
    - YCbCr-420 10 bpc CTA ITU-709 `ycbcr420_10bpc_cta_itu709`.
    - YCbCr-444 8 bpc CTA ITU-601 `ycbcr444_8bpc_cta_itu601`.
    - YCbCr-444 10 bpc CTA ITU-601 `ycbcr444_10bpc_cta_itu601`.
    - YCbCr-444 8 bpc CTA ITU-709 `ycbcr444_8bpc_cta_itu709`.
    - YCbCr-444 10 bpc CTA ITU-709 `ycbcr444_10bpc_cta_itu709`.
    """
    class __ColorMode:

        def __init__(self, value: int):
            self.value = value
            self.state = False

    def __init__(self, json_obj):
        self.__color_mode_count = Param(json_obj["TSI_DP14_SRCCTS_COLOR_FORMATS"])
        self.__rgb_6bpc_vesa = Param(json_obj["TSI_DP14_SRCCTS_COLOR_MODE_0"])
        self.__rgb_8bpc_vesa = Param(json_obj["TSI_DP14_SRCCTS_COLOR_MODE_1"])
        self.__rgb_10bpc_vesa = self.__ColorMode(make_cf(CMTFormat.RGB_LEGACY, CMTBitDepth.BPC_10))
        self.__rgb_8bpc_cta = self.__ColorMode(make_cf(CMTFormat.RGB_CEA, CMTBitDepth.BPC_8))
        self.__rgb_10bpc_cta = self.__ColorMode(make_cf(CMTFormat.RGB_CEA, CMTBitDepth.BPC_10))
        self.__ycbcr422_8bpc_cta_itu601 = self.__ColorMode(make_cf(CMTFormat.YCBCR_422_BT601, CMTBitDepth.BPC_8))
        self.__ycbcr422_10bpc_cta_itu601 = self.__ColorMode(make_cf(CMTFormat.YCBCR_422_BT601, CMTBitDepth.BPC_10))
        self.__ycbcr422_8bpc_cta_itu709 = self.__ColorMode(make_cf(CMTFormat.YCBCR_422_BT709, CMTBitDepth.BPC_8))
        self.__ycbcr422_10bpc_cta_itu709 = self.__ColorMode(make_cf(CMTFormat.YCBCR_422_BT709, CMTBitDepth.BPC_10))
        self.__ycbcr444_8bpc_cta_itu601 = self.__ColorMode(make_cf(CMTFormat.YCBCR_444_BT601, CMTBitDepth.BPC_8))
        self.__ycbcr444_10bpc_cta_itu601 = self.__ColorMode(make_cf(CMTFormat.YCBCR_444_BT601, CMTBitDepth.BPC_10))
        self.__ycbcr444_8bpc_cta_itu709 = self.__ColorMode(make_cf(CMTFormat.YCBCR_444_BT709, CMTBitDepth.BPC_8))
        self.__ycbcr444_10bpc_cta_itu709 = self.__ColorMode(make_cf(CMTFormat.YCBCR_444_BT709, CMTBitDepth.BPC_10))

        self.__color_mode_count.default_value = 2
        self.__queue = [
            Param(json_obj["TSI_DP14_SRCCTS_COLOR_MODE_2"]),
            Param(json_obj["TSI_DP14_SRCCTS_COLOR_MODE_3"]),
            Param(json_obj["TSI_DP14_SRCCTS_COLOR_MODE_4"]),
            Param(json_obj["TSI_DP14_SRCCTS_COLOR_MODE_5"]),
            Param(json_obj["TSI_DP14_SRCCTS_COLOR_MODE_6"]),
            Param(json_obj["TSI_DP14_SRCCTS_COLOR_MODE_7"]),
            Param(json_obj["TSI_DP14_SRCCTS_COLOR_MODE_8"]),
            Param(json_obj["TSI_DP14_SRCCTS_COLOR_MODE_9"]),
            Param(json_obj["TSI_DP14_SRCCTS_COLOR_MODE_10"]),
            Param(json_obj["TSI_DP14_SRCCTS_COLOR_MODE_11"]),
            Param(json_obj["TSI_DP14_SRCCTS_COLOR_MODE_12"])
        ]

    def __find_index_by_value(self, value: int) -> int:
        for index, item in enumerate(self.__queue):
            if item.default_value == value:
                return index
        return -1

    def __last_free_space_in_queue(self) -> int:
        return self.__find_index_by_value(0)

    def __shift_values_in_queue(self, index: int):
        for i in range(index, len(self.__queue) - 1):
            self.__queue[i].default_value = self.__queue[i + 1].default_value

    def __check_color_mode(self, color_mode):
        if color_mode.state:
            if self.__find_index_by_value(color_mode.value) == -1:
                self.__queue[self.__last_free_space_in_queue()].default_value = color_mode.value
                self.__color_mode_count.default_value += 1
        else:
            if self.__find_index_by_value(color_mode.value) != -1:
                index = self.__find_index_by_value(color_mode.value)
                self.__queue[index].default_value = 0
                self.__shift_values_in_queue(index)
                if self.__color_mode_count.default_value >= 3:
                    self.__color_mode_count.default_value -= 1

    @property
    def rgb_10bpc_vesa(self) -> bool:
        """
        Set and get RGB 10 bpc VESA flag support.

        Returns:
            object of bool type
        """
        return self.__rgb_10bpc_vesa.state

    @rgb_10bpc_vesa.setter
    def rgb_10bpc_vesa(self, rgb_10bpc_vesa: bool):
        if self.__rgb_10bpc_vesa.state != rgb_10bpc_vesa:
            self.__rgb_10bpc_vesa.state = rgb_10bpc_vesa
            self.__check_color_mode(self.__rgb_10bpc_vesa)

    @property
    def rgb_8bpc_cta(self) -> bool:
        """
        Set and get RGB 8 bpc CTA flag support.

        Returns:
            object of bool type
        """
        return self.__rgb_8bpc_cta.state

    @rgb_8bpc_cta.setter
    def rgb_8bpc_cta(self, rgb_8bpc_cta: bool):
        if self.__rgb_8bpc_cta.state != rgb_8bpc_cta:
            self.__rgb_8bpc_cta.state = rgb_8bpc_cta
            self.__check_color_mode(self.__rgb_8bpc_cta)

    @property
    def rgb_10bpc_cta(self) -> bool:
        """
        Set and get RGB 10 bpc CTA flag support.

        Returns:
            object of bool type
        """
        return self.__rgb_10bpc_cta.state

    @rgb_10bpc_cta.setter
    def rgb_10bpc_cta(self, rgb_10bpc_cta: bool):
        if self.__rgb_10bpc_cta.state != rgb_10bpc_cta:
            self.__rgb_10bpc_cta.state = rgb_10bpc_cta
            self.__check_color_mode(self.__rgb_10bpc_cta)

    @property
    def ycbcr422_8bpc_cta_itu601(self) -> bool:
        """
        Set and get YCbCr-422 8 bpc CTA ITU-601 flag support.

        Returns:
            object of bool type
        """
        return self.__ycbcr422_8bpc_cta_itu601.state

    @ycbcr422_8bpc_cta_itu601.setter
    def ycbcr422_8bpc_cta_itu601(self, ycbcr422_8bpc_cta_itu601: bool):
        if self.__ycbcr422_8bpc_cta_itu601.state != ycbcr422_8bpc_cta_itu601:
            self.__ycbcr422_8bpc_cta_itu601.state = ycbcr422_8bpc_cta_itu601
            self.__check_color_mode(self.__ycbcr422_8bpc_cta_itu601)

    @property
    def ycbcr422_10bpc_cta_itu601(self) -> bool:
        """
        Set and get YCbCr-422 10 bpc CTA ITU-601 flag support.

        Returns:
            object of bool type
        """
        return self.__ycbcr422_10bpc_cta_itu601.state

    @ycbcr422_10bpc_cta_itu601.setter
    def ycbcr422_10bpc_cta_itu601(self, ycbcr422_10bpc_cta_itu601: bool):
        if self.__ycbcr422_10bpc_cta_itu601.state != ycbcr422_10bpc_cta_itu601:
            self.__ycbcr422_10bpc_cta_itu601.state = ycbcr422_10bpc_cta_itu601
            self.__check_color_mode(self.__ycbcr422_10bpc_cta_itu601)

    @property
    def ycbcr422_8bpc_cta_itu709(self) -> bool:
        """
        Set and get YCbCr-422 8 bpc CTA ITU-709 flag support.

        Returns:
            object of bool type
        """
        return self.__ycbcr422_8bpc_cta_itu709.state

    @ycbcr422_8bpc_cta_itu709.setter
    def ycbcr422_8bpc_cta_itu709(self, ycbcr422_8bpc_cta_itu709: bool):
        if self.__ycbcr422_8bpc_cta_itu709.state != ycbcr422_8bpc_cta_itu709:
            self.__ycbcr422_8bpc_cta_itu709.state = ycbcr422_8bpc_cta_itu709
            self.__check_color_mode(self.__ycbcr422_8bpc_cta_itu709)

    @property
    def ycbcr422_10bpc_cta_itu709(self) -> bool:
        """
        Set and get YCbCr-422 10 bpc CTA ITU-709 flag support.

        Returns:
            object of bool type
        """
        return self.__ycbcr422_10bpc_cta_itu709.state

    @ycbcr422_10bpc_cta_itu709.setter
    def ycbcr422_10bpc_cta_itu709(self, ycbcr422_10bpc_cta_itu709: bool):
        if self.__ycbcr422_10bpc_cta_itu709.state != ycbcr422_10bpc_cta_itu709:
            self.__ycbcr422_10bpc_cta_itu709.state = ycbcr422_10bpc_cta_itu709
            self.__check_color_mode(self.__ycbcr422_10bpc_cta_itu709)

    @property
    def ycbcr444_8bpc_cta_itu601(self) -> bool:
        """
        Set and get YCbCr-444 8 bpc CTA ITU-601 flag support.

        Returns:
            object of bool type
        """
        return self.__ycbcr444_8bpc_cta_itu601.state

    @ycbcr444_8bpc_cta_itu601.setter
    def ycbcr444_8bpc_cta_itu601(self, ycbcr444_8bpc_cta_itu601: bool):
        if self.__ycbcr444_8bpc_cta_itu601.state != ycbcr444_8bpc_cta_itu601:
            self.__ycbcr444_8bpc_cta_itu601.state = ycbcr444_8bpc_cta_itu601
            self.__check_color_mode(self.__ycbcr444_8bpc_cta_itu601)

    @property
    def ycbcr444_10bpc_cta_itu601(self) -> bool:
        """
        Set and get YCbCr-444 10 bpc CTA ITU-601 flag support.

        Returns:
            object of bool type
        """
        return self.__ycbcr444_10bpc_cta_itu601.state

    @ycbcr444_10bpc_cta_itu601.setter
    def ycbcr444_10bpc_cta_itu601(self, ycbcr444_10bpc_cta_itu601: bool):
        if self.__ycbcr444_10bpc_cta_itu601.state != ycbcr444_10bpc_cta_itu601:
            self.__ycbcr444_10bpc_cta_itu601.state = ycbcr444_10bpc_cta_itu601
            self.__check_color_mode(self.__ycbcr444_10bpc_cta_itu601)

    @property
    def ycbcr444_8bpc_cta_itu709(self) -> bool:
        """
        Set and get YCbCr-444 8 bpc CTA ITU-709 flag support.

        Returns:
            object of bool type
        """
        return self.__ycbcr444_8bpc_cta_itu709.state

    @ycbcr444_8bpc_cta_itu709.setter
    def ycbcr444_8bpc_cta_itu709(self, ycbcr444_8bpc_cta_itu709: bool):
        if self.__ycbcr444_8bpc_cta_itu709.state != ycbcr444_8bpc_cta_itu709:
            self.__ycbcr444_8bpc_cta_itu709.state = ycbcr444_8bpc_cta_itu709
            self.__check_color_mode(self.__ycbcr444_8bpc_cta_itu709)

    @property
    def ycbcr444_10bpc_cta_itu709(self) -> bool:
        """
        Set and get YCbCr-444 10 bpc CTA ITU-709 flag support.

        Returns:
            object of bool type
        """
        return self.__ycbcr444_10bpc_cta_itu709.state

    @ycbcr444_10bpc_cta_itu709.setter
    def ycbcr444_10bpc_cta_itu709(self, ycbcr444_10bpc_cta_itu709: bool):
        if self.__ycbcr444_10bpc_cta_itu709.state != ycbcr444_10bpc_cta_itu709:
            self.__ycbcr444_10bpc_cta_itu709.state = ycbcr444_10bpc_cta_itu709
            self.__check_color_mode(self.__ycbcr444_10bpc_cta_itu709)

    def clear_all(self):
        """
        Clear all settings.
        """
        self.rgb_10bpc_vesa = False
        self.rgb_8bpc_cta = False
        self.rgb_10bpc_cta = False
        self.ycbcr422_8bpc_cta_itu601 = False
        self.ycbcr422_10bpc_cta_itu601 = False
        self.ycbcr422_8bpc_cta_itu709 = False
        self.ycbcr422_10bpc_cta_itu709 = False
        self.ycbcr444_8bpc_cta_itu601 = False
        self.ycbcr444_10bpc_cta_itu601 = False
        self.ycbcr444_8bpc_cta_itu709 = False
        self.ycbcr444_10bpc_cta_itu709 = False

        for item in self.__queue:
            item.default_value = 0

    def select_all(self):
        """
        Select all modes.
        """
        self.rgb_10bpc_vesa = True
        self.rgb_8bpc_cta = True
        self.rgb_10bpc_cta = True
        self.ycbcr422_8bpc_cta_itu601 = True
        self.ycbcr422_10bpc_cta_itu601 = True
        self.ycbcr422_8bpc_cta_itu709 = True
        self.ycbcr422_10bpc_cta_itu709 = True
        self.ycbcr444_8bpc_cta_itu601 = True
        self.ycbcr444_10bpc_cta_itu601 = True
        self.ycbcr444_8bpc_cta_itu709 = True
        self.ycbcr444_10bpc_cta_itu709 = True


class DebugOptions:

    def __init__(self, json_obj):
        self.__param = Param(json_obj["TSI_DP14_SRCCTS_DUT_DEBUG_CONF"])

    @property
    def continue_on_fail(self) -> bool:
        """
        Set and get continue on fail flag.

        Returns:
            object of bool type
        """
        return self.__param._get_by_bitmask(0, bool)

    @continue_on_fail.setter
    def continue_on_fail(self, continue_on_fail: bool):
        self.__param.default_value = update_default_value(value=continue_on_fail,
                                                          default_value=self.__param.default_value,
                                                          mask=self.__param.bit_field_list[0].mask)


class GeneralSourceDUTDp14SettingTab:
    """
    Class `GeneralSourceDUTDp14SettingTab` allows working with parameters from General source part.
    - Set and get timeout `timeout`.
    - Set and get DUT capabilities `dut_caps` type `DutCapsDp14`.
    - Set and get test automation flags `test_automation` type `TestAutomationFlags`.
    - Set and get HPD pulse duration `hpd_pulse_duration`.
    - Set and get link training start timeout `lt_start_timeout`.
    - Set and get test cycle delay `test_cycle_delay`.
    - Get fail safe mode `fail_safe_mode`.
    - Set and get maximum supported video modes `max_supported_video_mode` type `MaxSupportedVideoMode`.
    - Set and get packed timings for 1 lane `packed_timings_1_lane` type `PackedTimings1Lane`.
    - Set and get packed timings for 2 lane `packed_timings_2_lane` type `PackedTimings2Lane`.
    - Set and get packed timings for 4 lane `packed_timings_4_lane` type `PackedTimings4Lane`.
    - Set and get time stamp generation `time_stamp_generation` type `TimeStampGenerationDp14`.
    - Set and get colorimetry modes `colorimetry` type `ColorimetryDp14`.
    - Set and get debug options `debug_options` type `DebugOptions`
    """
    def __init__(self, json_obj):
        self.__timeout = Param(json_obj["TSI_DP14_SRCCTS_TIMEOUT"])
        self.__dut_caps = DutCapsDp14(json_obj)
        self.__test_automation = TestAutomationFlags(json_obj["TSI_DP14_SRCCTS_DUT_TA"])
        self.__hpd_pulse_duration = Param(json_obj["TSI_DP14_SRCCTS_LONG_HPD_PULSE"])
        self.__lt_start_timeout = Param(json_obj["TSI_DP14_SRCCTS_LT_START_TIMEOUT"])
        self.__test_cycle_delay = Param(json_obj["TSI_DP14_SRCCTS_TEST_CYCLE_DELAY"])
        self.__fail_safe_mode = Param(json_obj["TSI_DP14_SRCCTS_FAILSAFE_MODE"])
        self.__max_supported_video_mode = Param(json_obj["TSI_DP14_SRCCTS_MAX_RESOLUTION"])  # MaxSupportedVideoMode Enum
        self.__packed_timings_1_lane = Param(json_obj["TSI_DP14_SRCCTS_1L_MOST_PACKED"])  # PackedTimings1Lane
        self.__packed_timings_2_lane = Param(json_obj["TSI_DP14_SRCCTS_2L_MOST_PACKED"])  # PackedTimings2Lane
        self.__packed_timings_4_lane = Param(json_obj["TSI_DP14_SRCCTS_4L_MOST_PACKED"])  # PackedTimings4Lane
        self.__time_stamp_generation = TimeStampGenerationDp14(json_obj)
        self.__colorimetry = ColorimetryDp14(json_obj)
        self.__debug_options = DebugOptions(json_obj)

    @property
    def timeout(self) -> int:
        """
        Set and get test timeout, in milliseconds.

        Returns:
            object of int type
        """
        return self.__timeout.default_value

    @timeout.setter
    def timeout(self, timeout: int):
        if not(self.__timeout.min_value < timeout < self.__timeout.max_value):
            raise ValueError(f"Timeout cannot be less than {self.__timeout.min_value} and more than "
                             f"{self.__timeout.max_value}.")
        self.__timeout.default_value = timeout

    @property
    def dut_caps(self):
        """
        Set and get DUT caps.

        Returns:
            object DutCapsDp14
        """
        return self.__dut_caps

    @dut_caps.setter
    def dut_caps(self, dut_caps: DutCapsDp14):
        self.__dut_caps = dut_caps

    @property
    def test_automation(self) -> TestAutomationFlags:
        """
        Set and get test automation flags.

        Returns:
            object TestAutomationFlags
        """
        return self.__test_automation

    @test_automation.setter
    def test_automation(self, test_automation: TestAutomationFlags):
        self.__test_automation = test_automation

    @property
    def hpd_pulse_duration(self) -> int:
        """
        Set and get HPD pulse duration.

        Returns:
            object of int type
        """
        return self.__hpd_pulse_duration.default_value

    @hpd_pulse_duration.setter
    def hpd_pulse_duration(self, hpd_pulse_duration: int):
        if not(self.__hpd_pulse_duration.min_value < hpd_pulse_duration < self.__hpd_pulse_duration.max_value):
            raise ValueError(f"HPD pulse duration cannot be less than {self.__timeout.min_value} and more than "
                             f"{self.__hpd_pulse_duration.max_value}.")
        self.__hpd_pulse_duration.default_value = hpd_pulse_duration

    @property
    def lt_start_timeout(self) -> int:
        """
        Set and get link training start timeout.

        Returns:
            object of int type
        """
        return self.__lt_start_timeout.default_value

    @lt_start_timeout.setter
    def lt_start_timeout(self, lt_start_timeout: int):
        if not(self.__lt_start_timeout.min_value < lt_start_timeout < self.__lt_start_timeout.max_value):
            raise ValueError(f"LT start timeout cannot be less than {self.__lt_start_timeout.min_value} and more than "
                             f"{self.__lt_start_timeout.max_value}.")
        self.__lt_start_timeout.default_value = lt_start_timeout

    @property
    def test_cycle_delay(self) -> int:
        """
        Set and get test cycle delay.

        Returns:
            object of int type
        """
        return self.__test_cycle_delay.default_value

    @test_cycle_delay.setter
    def test_cycle_delay(self, test_cycle_delay: int):
        if not(self.__test_cycle_delay.min_value < test_cycle_delay < self.__test_cycle_delay.max_value):
            raise ValueError(f"Test cycle delay cannot be less than {self.__test_cycle_delay.min_value} and more than "
                             f"{self.__test_cycle_delay.max_value}.")
        self.__test_cycle_delay.default_value = test_cycle_delay

    @property
    def fail_safe_mode(self):
        """
        Get fail safe mode.

        Returns:
            object of int type
        """
        return self.__fail_safe_mode.default_value

    @property
    def max_supported_video_mode(self):
        """
        Set and get maximum supported video modes.

        Returns:
            object MaxSupportedVideoMode
        """
        return self.__max_supported_video_mode

    @max_supported_video_mode.setter
    def max_supported_video_mode(self, max_supported_video_mode: MaxSupportedVideoMode):
        self.__max_supported_video_mode.default_value = max_supported_video_mode.value

    @property
    def packed_timings_1_lane(self):
        """
        Set and get packed timings for 1 lane.

        Returns:
            object PackedTimings1Lane
        """
        return self.__packed_timings_1_lane

    @packed_timings_1_lane.setter
    def packed_timings_1_lane(self, packed_timings_1_lane: PackedTimings1Lane):
        self.__packed_timings_1_lane.default_value = packed_timings_1_lane.value

    @property
    def packed_timings_2_lane(self):
        """
        Set and get packed timings for 2 lane.

        Returns:
            object PackedTimings2Lane
        """
        return self.__packed_timings_2_lane

    @packed_timings_2_lane.setter
    def packed_timings_2_lane(self, packed_timings_2_lane: PackedTimings2Lane):
        self.__packed_timings_2_lane.default_value = packed_timings_2_lane.value

    @property
    def packed_timings_4_lane(self):
        """
        Set and get packed timings for 4 lane.

        Returns:
            object PackedTimings4Lane
        """
        return self.__packed_timings_4_lane

    @packed_timings_4_lane.setter
    def packed_timings_4_lane(self, packed_timings_4_lane: PackedTimings4Lane):
        self.__packed_timings_4_lane.default_value = packed_timings_4_lane.value

    @property
    def time_stamp_generation(self):
        """
        Set and get time stamp generation.

        Returns:
            object TimeStampGenerationDp14
        """
        return self.__time_stamp_generation

    @time_stamp_generation.setter
    def time_stamp_generation(self, time_stamp_generation: TimeStampGenerationDp14):
        self.__time_stamp_generation = time_stamp_generation

    @property
    def colorimetry(self) -> ColorimetryDp14:
        """
        Set and get colorimetry modes.

        Returns:
            object ColorimetryDp14
        """
        return self.__colorimetry

    @colorimetry.setter
    def colorimetry(self, colorimetry: ColorimetryDp14):
        self.__colorimetry = colorimetry

    @property
    def debug_options(self) -> DebugOptions:
        """
        Set and get debug options.

        Returns:
            object of 'DebugOptions' type
        """
        return self.__debug_options

    @debug_options.setter
    def debug_options(self, debug_config: DebugOptions):
        self.__debug_options = debug_config
