from UniTAP.dev.modules.dut_tests.test_group_params_types import Param
from .dp_1_4_source_general_tab import TestAutomationFlags, update_default_value


class LttprDutCapsFlags(Param):
    """
        Class `LttprDutCapsFlags` defines the DUT capabilities as flags and allows setting:
        - Define that DUT is Type-C device `dut_is_type_c_device`.
        """

    def __init__(self, json_obj):
        super().__init__(json_obj)

    @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(0, 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, 0)

    def set_all_caps(self):
        """
        Set all setting.
        """
        self.dut_is_type_c_device = True

    def clear_all_caps(self):
        """
        Clear all settings.
        """
        self.dut_is_type_c_device = False


class DebugOptions:
    def __init__(self, json_obj):
        self.__cr_iteration_delay = Param(json_obj["TSI_DP20_LTTPR_DEBUG_CR_ITERATION_DELAY"])

    @property
    def cr_iteration_delay(self) -> bool:
        """
        Set and get Force manual visual check flag.

        Returns:
            object of bool type
        """
        return self.__cr_iteration_delay.default_value

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


class DpLttprTestParam:
    """
    Class `DpLttprTestParam` describes requirement parameters for LTTPR DP 1228b/132b tests:
    - Set and get `timeout`. Describes test timeout, in milliseconds.
    - Set and get `hpd_duration`. Describes duration of long HPD pulses generated, in milliseconds.
    - Set and get `dut_caps_flag`. Describes source DUT capabilities flags.
    """
    def __init__(self, json_obj):
        self.__timeout = Param(json_obj["TSI_DP20_LTTPR_TIMEOUT"])
        self.__max_lanes = Param(json_obj["TSI_DP20_LTTPR_MAX_LANES"])  # Not access
        self.__max_link_rate = Param(json_obj["TSI_DP20_LTTPR_MAX_LINK_RATE"])  # Not access
        self.__dut_caps = LttprDutCapsFlags(json_obj["TSI_DP20_LTTPR_DUT_CAPS"])
        self.__test_automation = TestAutomationFlags(json_obj["TSI_DP20_LTTPR_DUT_TA"])  # Not access
        self.__hpd_duration = Param(json_obj["TSI_DP20_LTTPR_LONG_HPD_PULSE"])
        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 hpd_duration(self) -> int:
        """
        Set and get duration of long HPD pulses generated, in milliseconds.

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

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

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

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

    @dut_caps_flags.setter
    def dut_caps_flags(self, dut_caps_flags: LttprDutCapsFlags):
        self.__dut_caps = dut_caps_flags
