import typing

from sila import Native, datetime
from unitelabs.cdk import sila


class ParameterConstraintsTest(sila.Feature):
    """
    This is a test feature to generically test constrained parameters.

    A validation Error must be raised if a constraint is not fulfilled.
    """

    def __init__(self):
        super().__init__(originator="org.silastandard", category="test")

    # String type constraints

    @sila.UnobservableCommand()
    async def check_string_constraint_length(
        self, constrained_parameter: typing.Annotated[str, sila.constraints.Length(10)]
    ) -> None:
        """
        Test the Length constraint on the String type.

        Args:
          ConstrainedParameter: A String parameter with a Length constraint of 10
        """

    @sila.UnobservableCommand()
    async def check_string_constraint_minimal_length(
        self, constrained_parameter: typing.Annotated[str, sila.constraints.MinimalLength(5)]
    ) -> None:
        """
        Test the MinimalLength constraint on the String type.

        Args:
          ConstrainedParameter: A String parameter with a MinimalLength constraint of 5
        """

    @sila.UnobservableCommand()
    async def check_string_constraint_maximal_length(
        self, constrained_parameter: typing.Annotated[str, sila.constraints.MaximalLength(20)]
    ) -> None:
        """
        Test the MaximalLength constraint on the String type.

        Args:
          ConstrainedParameter: A String parameter with a MaximalLength constraint of 20
        """

    @sila.UnobservableCommand()
    async def check_string_constraint_minmax_length(
        self,
        constrained_parameter: typing.Annotated[
            str, sila.constraints.MinimalLength(5), sila.constraints.MaximalLength(20)
        ],
    ) -> None:
        """
        Test the combination of MinimalLength and MaximalLength constraints on the String type.

        Args:
          ConstrainedParameter: A String parameter with a MinimalLength constraint of 5
            and a MaximalLength constraint of 20
        """

    @sila.UnobservableCommand()
    async def check_string_constraint_set(
        self,
        constrained_parameter: typing.Annotated[
            str, sila.constraints.Set(["First option", "Second option", "Third option"])
        ],
    ) -> None:
        """
        Test the Set constraint on the String type.

        Args:
          ConstrainedParameter: A String parameter with a Set constraint of
            'First option', 'Second option', 'Third option'
        """

    @sila.UnobservableCommand()
    async def check_string_constraint_pattern(
        self,
        constrained_parameter: typing.Annotated[str, sila.constraints.Pattern(r"[0-9]{2}/[0-9]{2}/[0-9]{4}")],
    ) -> None:
        """
        Test the Pattern constraint on String type.

        Args:
          ConstrainedParameter: A String parameter with a Pattern constraint
            of a date of birth in dd/mm/yyyy format
        """

    @sila.UnobservableCommand()
    async def check_string_constraint_content_type(
        self,
        constrained_parameter: typing.Annotated[str, sila.constraints.ContentType("application", "xml")],
    ) -> None:
        """
        Test the ContentType constraint on the String type.

        Args:
          ConstrainedParameter: A String parameter with a ContentType constraint
            allowing only valid XML document as content
        """

    @sila.UnobservableCommand()
    async def check_string_constraint_fully_qualified_identifier(
        self,
        feature_identifier: typing.Annotated[str, sila.constraints.FullyQualifiedIdentifier("FeatureIdentifier")],
        command_identifier: typing.Annotated[str, sila.constraints.FullyQualifiedIdentifier("CommandIdentifier")],
        command_parameter_identifier: typing.Annotated[
            str, sila.constraints.FullyQualifiedIdentifier("CommandParameterIdentifier")
        ],
        command_response_identifier: typing.Annotated[
            str, sila.constraints.FullyQualifiedIdentifier("CommandResponseIdentifier")
        ],
        intermediate_command_response_identifier: typing.Annotated[
            str, sila.constraints.FullyQualifiedIdentifier("IntermediateCommandResponseIdentifier")
        ],
        execution_error_identifier: typing.Annotated[
            str, sila.constraints.FullyQualifiedIdentifier("DefinedExecutionErrorIdentifier")
        ],
        property_identifier: typing.Annotated[str, sila.constraints.FullyQualifiedIdentifier("PropertyIdentifier")],
        custom_data_type_identifier: typing.Annotated[str, sila.constraints.FullyQualifiedIdentifier("TypeIdentifier")],
        metadata_identifier: typing.Annotated[str, sila.constraints.FullyQualifiedIdentifier("MetadataIdentifier")],
    ) -> None:
        """
        Test the FullyQualifiedIdentifier constraint on the String type.

        Args:
          FeatureIdentifier: Tests that the parameter is a valid feature identifier
          CommandIdentifier: Tests that the parameter is a valid command identifier
          CommandParameterIdentifier: Tests that the parameter is a valid command parameter identifier
          CommandResponseIdentifier: Tests that the parameter is a valid command response identifier
          IntermediateCommandResponseIdentifier: Tests that the parameter is a valid intermediate
            command response identifier
          ExecutionErrorIdentifier: Tests that the parameter is a valid execution error identifier
          PropertyIdentifier: Tests that the parameter is a valid property identifier
          CustomDataTypeIdentifier: Tests that the parameter is a valid data type identifier
          MetadataIdentifier: Tests that the parameter is a valid metadata identifier
        """

    @sila.UnobservableCommand()
    async def check_string_constraint_schema(
        self,
        constrained_parameter: typing.Annotated[
            str,
            sila.constraints.Schema(
                "Xml",
                url="https://gitlab.com/SiLA2/sila_base/-/raw/master/schema/FeatureDefinition.xsd",
            ),
        ],
    ) -> None:
        """
        Test that the parameter is valid for a given Schema constraint.

        Args:
          ConstrainedParameter: A String parameter with a Schema constraint allowing only content that
            is compliant with the SiLA 2 Feature Definition schema
        """

    # Integer type constraints

    @sila.UnobservableCommand()
    async def check_integer_constraint_set(
        self, constrained_parameter: typing.Annotated[int, sila.constraints.Set([1, 2, 3])]
    ) -> None:
        """
        Test the Set constraint on the Integer type.

        Args:
          ConstrainedParameter: An Integer parameter with a Set constraint of 1, 2, 3
        """

    @sila.UnobservableCommand()
    async def check_scientifically_notated_integer_limit(
        self,
        constrained_parameter: typing.Annotated[
            int, sila.constraints.MinimalInclusive(int(-1e3)), sila.constraints.MaximalExclusive(int(1.23e5))
        ],
    ) -> None:
        """
        Test if scientific notation is accepted for checking limits of type Integer.

        Args:
          ConstrainedParameter: An Integer parameter with a MinimalInclusive constraint
            of -1e3 and a MaximalExclusive constraint of 1.23e5
        """

    @sila.UnobservableCommand()
    async def check_integer_constraint_maximal_exclusive(
        self,
        constrained_parameter: typing.Annotated[int, sila.constraints.MaximalExclusive(11)],
    ) -> None:
        """
        Test the MaximalExclusive constraint on the Integer type.

        Args:
          ConstrainedParameter: An Integer parameter with a MaximalExclusive constraint of 11
        """

    @sila.UnobservableCommand()
    async def check_integer_constraint_maximal_inclusive(
        self,
        constrained_parameter: typing.Annotated[int, sila.constraints.MaximalInclusive(10)],
    ) -> None:
        """
        Test the MaximalInclusive constraint on the Integer type.

        Args:
          ConstrainedParameter: An Integer parameter with a MaximalInclusive constraint of 10
        """

    @sila.UnobservableCommand()
    async def check_integer_constraint_minimal_exclusive(
        self,
        constrained_parameter: typing.Annotated[int, sila.constraints.MinimalExclusive(-1)],
    ) -> None:
        """
        Test the MinimalExclusive constraint on the Integer type.

        Args:
          ConstrainedParameter: An Integer parameter with a MinimalExclusive constraint of -1
        """

    @sila.UnobservableCommand()
    async def check_integer_constraint_minimal_inclusive(
        self,
        constrained_parameter: typing.Annotated[int, sila.constraints.MinimalInclusive(0)],
    ) -> None:
        """
        Test the MinimalInclusive constraint on the Integer type.

        Args:
          ConstrainedParameter: An Integer parameter with a MinimalInclusive constraint of 0
        """

    @sila.UnobservableCommand()
    async def check_integer_constraint_minmax(
        self,
        constrained_parameter: typing.Annotated[
            int, sila.constraints.MinimalExclusive(-1), sila.constraints.MaximalInclusive(10)
        ],
    ) -> None:
        """
        Test the combination of MinimalExclusive and MaximalInclusive constraints on Integer type.

        Args:
          ConstrainedParameter: An Integer parameter with a MinimalExclusive constraint of -1 and
            a MaximalInclusive constraint of 10
        """

    @sila.UnobservableCommand()
    async def check_integer_constraint_unit(
        self,
        constrained_parameter: typing.Annotated[
            int, sila.constraints.Unit("mL", [sila.constraints.UnitComponent("Meter", 3)], factor=0.000001)
        ],
    ) -> None:
        """
        Test the Unit constraint on the Integer type.

        Args:
          ConstrainedParameter: An Integer parameter with a Unit constraint for milliliter (mL)
        """

    # Real type constraints

    @sila.UnobservableCommand()
    async def check_real_constraint_set(
        self, constrained_parameter: typing.Annotated[float, sila.constraints.Set([1.11, 2.22, 3.33])]
    ) -> None:
        """
        Test the Set constraint on the Real type.

        Args:
          ConstrainedParameter: A Real parameter with a Set constraint of 1.11, 2.22, 3.33
        """

    @sila.UnobservableCommand()
    async def check_scientifically_notated_real_limit(
        self,
        constrained_parameter: typing.Annotated[
            float, sila.constraints.MinimalInclusive(1.23e-3), sila.constraints.MaximalExclusive(1.23456e2)
        ],
    ) -> None:
        """
        Test if scientific notation is accepted for checking limits of type Real.

        Args:
          ConstrainedParameter: A Real parameter with a MinimalInclusive constraint
            of 1.23e-3 and a MaximalExclusive constraint of 1.23456e2
        """

    @sila.UnobservableCommand()
    async def check_real_constraint_maximal_exclusive(
        self,
        constrained_parameter: typing.Annotated[float, sila.constraints.MaximalExclusive(10.5)],
    ) -> None:
        """
        Test the MaximalExclusive constraint on the Real type.

        Args:
          ConstrainedParameter: A Real parameter with a MaximalExclusive constraint of 10.5
        """

    @sila.UnobservableCommand()
    async def check_real_constraint_maximal_inclusive(
        self,
        constrained_parameter: typing.Annotated[float, sila.constraints.MaximalInclusive(10)],
    ) -> None:
        """
        Test the MaximalInclusive constraint on the Real type.

        Args:
          ConstrainedParameter: A Real parameter with a MaximalInclusive constraint of 10
        """

    @sila.UnobservableCommand()
    async def check_real_constraint_minimal_exclusive(
        self,
        constrained_parameter: typing.Annotated[float, sila.constraints.MinimalExclusive(0)],
    ) -> None:
        """
        Test the MinimalExclusive constraint on the Real type.

        Args:
          ConstrainedParameter: A Real parameter with a MinimalExclusive constraint of 0
        """

    @sila.UnobservableCommand()
    async def check_real_constraint_minimal_inclusive(
        self,
        constrained_parameter: typing.Annotated[float, sila.constraints.MinimalInclusive(-1.5)],
    ) -> None:
        """
        Test the MinimalInclusive constraint on the Real type.

        Args:
          ConstrainedParameter: A Real parameter with a MinimalInclusive constraint of -1.5
        """

    @sila.UnobservableCommand()
    async def check_real_constraint_minmax(
        self,
        constrained_parameter: typing.Annotated[
            float, sila.constraints.MinimalExclusive(0.333), sila.constraints.MaximalInclusive(11.111)
        ],
    ) -> None:
        """
        Test the combination of MinimalExclusive and MaximalInclusive constraints on Real type.

        Args:
          ConstrainedParameter: A Real parameter with a MinimalExclusive constraint of 0.333 and
            a MaximalInclusive constraint of 11.111
        """

    @sila.UnobservableCommand()
    async def check_real_constraint_unit(
        self,
        constrained_parameter: typing.Annotated[
            float, sila.constraints.Unit("°C", [sila.constraints.UnitComponent("Kelvin", 1)], offset=273.15)
        ],
    ) -> None:
        """
        Test the Unit constraint on the Real type.

        Args:
          ConstrainedParameter: A Real parameter with a Unit constraint for degree celsius (°C)
        """

    # Date type constraints

    @sila.UnobservableCommand()
    async def check_date_constraint_set(
        self,
        constrained_parameter: typing.Annotated[
            datetime.date,
            sila.constraints.Set(
                [
                    datetime.date(2022, 9, 10),
                    datetime.date(2022, 9, 11, tzinfo=datetime.timezone(datetime.timedelta(hours=-1, minutes=45))),
                    datetime.date(2022, 9, 12, tzinfo=datetime.timezone(datetime.timedelta(hours=11, minutes=30))),
                ]
            ),
        ],
    ) -> None:
        """
        Test the Set constraint on the Date type.

        Args:
          ConstrainedParameter: A Date parameter with a Set constraint of
            2022-09-10Z, 2022-09-11-00:15, 2022-09-12+11:30
        """

    @sila.UnobservableCommand()
    async def check_date_constraint_maximal_exclusive(
        self,
        constrained_parameter: typing.Annotated[
            datetime.date,
            sila.constraints.MaximalExclusive(
                datetime.date(2019, 12, 31, tzinfo=datetime.timezone(datetime.timedelta(hours=2, minutes=30)))
            ),
        ],
    ) -> None:
        """
        Test the MaximalExclusive constraint on the Date type.

        Args:
          ConstrainedParameter: A Date parameter with a MaximalExclusive constraint of 2019-12-31+02:30
        """

    @sila.UnobservableCommand()
    async def check_date_constraint_maximal_inclusive(
        self,
        constrained_parameter: typing.Annotated[
            datetime.date,
            sila.constraints.MaximalInclusive(
                datetime.date(2025, 12, 31, tzinfo=datetime.timezone(datetime.timedelta(hours=-2, minutes=30)))
            ),
        ],
    ) -> None:
        """
        Test the MaximalInclusive constraint on the Date type.

        Args:
          ConstrainedParameter: A Date parameter with a MaximalInclusive constraint of 2025-12-31-01:30
        """

    @sila.UnobservableCommand()
    async def check_date_constraint_minimal_exclusive(
        self,
        constrained_parameter: typing.Annotated[
            datetime.date,
            sila.constraints.MinimalExclusive(
                datetime.date(2019, 1, 1, tzinfo=datetime.timezone(datetime.timedelta(hours=-1, minutes=0)))
            ),
        ],
    ) -> None:
        """
        Test the MinimalExclusive constraint on the Date type.

        Args:
          ConstrainedParameter: A Date parameter with a MinimalExclusive constraint of 2019-01-01-01:00
        """

    @sila.UnobservableCommand()
    async def check_date_constraint_minimal_inclusive(
        self,
        constrained_parameter: typing.Annotated[
            datetime.date,
            sila.constraints.MinimalInclusive(
                datetime.date(1789, 7, 14, tzinfo=datetime.timezone(datetime.timedelta(hours=2, minutes=0)))
            ),
        ],
    ) -> None:
        """
        Test the MinimalInclusive constraint on the Date type.

        Args:
          ConstrainedParameter: A Date parameter with a MinimalInclusive constraint of 1789-07-14+02:00
        """

    @sila.UnobservableCommand()
    async def check_date_constraint_minmax(
        self,
        constrained_parameter: typing.Annotated[
            datetime.date,
            sila.constraints.MinimalExclusive(
                datetime.date(1976, 6, 1, tzinfo=datetime.timezone(datetime.timedelta(hours=2, minutes=0)))
            ),
            sila.constraints.MaximalInclusive(
                datetime.date(2076, 6, 10, tzinfo=datetime.timezone(datetime.timedelta(hours=2, minutes=0)))
            ),
        ],
    ) -> None:
        """
        Test the combination of MinimalInclusive and MaximalExclusive constraints on Date type.

        Args:
          ConstrainedParameter: A Date parameter with a MinimalInclusive constraint of 1976-06-10+02:00 and
            a MaximalExclusive constraint of 2076-06-10+02:00
        """

    # Time type constraints

    @sila.UnobservableCommand()
    async def check_time_constraint_set(
        self,
        constrained_parameter: typing.Annotated[
            datetime.time,
            sila.constraints.Set(
                [
                    datetime.time(18, 59, 59, 999000, tzinfo=datetime.timezone(datetime.timedelta(hours=2))),
                    datetime.time(19, 0, 0, 0, tzinfo=datetime.timezone(datetime.timedelta(hours=-1, minutes=45))),
                    datetime.time(19, 59, 0, 123000),
                ]
            ),
        ],
    ) -> None:
        """
        Test the Set constraint on the Time type.

        Args:
          ConstrainedParameter: A Time parameter with a Set constraint of
            18:59:59.999+02:00, 19:00:00.000-00:15, 19:59:00.123Z
        """

    @sila.UnobservableCommand()
    async def check_time_constraint_maximal_exclusive(
        self,
        constrained_parameter: typing.Annotated[
            datetime.time,
            sila.constraints.MaximalExclusive(
                datetime.time(12, 0, 0, 0, tzinfo=datetime.timezone(datetime.timedelta(hours=0, minutes=15)))
            ),
        ],
    ) -> None:
        """
        Test the MaximalExclusive constraint on the Time type.

        Args:
          ConstrainedParameter: A Time parameter with a MaximalExclusive constraint of 12:00:00.000+00:15
        """

    @sila.UnobservableCommand()
    async def check_time_constraint_maximal_inclusive(
        self,
        constrained_parameter: typing.Annotated[
            datetime.time,
            sila.constraints.MaximalInclusive(
                datetime.time(18, 59, 59, 987000, tzinfo=datetime.timezone(datetime.timedelta(hours=2)))
            ),
        ],
    ) -> None:
        """
        Test the MaximalInclusive constraint on the Time type.

        Args:
          ConstrainedParameter: A Time parameter with a MaximalInclusive constraint of 18:59:59.987+02:00
        """

    @sila.UnobservableCommand()
    async def check_time_constraint_minimal_exclusive(
        self,
        constrained_parameter: typing.Annotated[
            datetime.time,
            sila.constraints.MinimalExclusive(
                datetime.time(1, 2, 3, 456000, tzinfo=datetime.timezone(datetime.timedelta(hours=7)))
            ),
        ],
    ) -> None:
        """
        Test the MinimalExclusive constraint on the Time type.

        Args:
          ConstrainedParameter: A Time parameter with a MinimalExclusive constraint of 01:02:03.456+07:00
        """

    @sila.UnobservableCommand()
    async def check_time_constraint_minimal_inclusive(
        self,
        constrained_parameter: typing.Annotated[
            datetime.time,
            sila.constraints.MinimalInclusive(datetime.time(8, 0, 0, 555000)),
        ],
    ) -> None:
        """
        Test the MinimalInclusive constraint on the Time type.

        Args:
          ConstrainedParameter: A Time parameter with a MinimalInclusive constraint of 08:00.555Z
        """

    @sila.UnobservableCommand()
    async def check_time_constraint_minmax(
        self,
        constrained_parameter: typing.Annotated[
            datetime.time,
            sila.constraints.MinimalExclusive(
                datetime.time(8, 0, 0, 500000, tzinfo=datetime.timezone(datetime.timedelta(hours=-3, minutes=30)))
            ),
            sila.constraints.MaximalInclusive(
                datetime.time(18, 59, 59, 595000, tzinfo=datetime.timezone(datetime.timedelta(hours=2, minutes=30)))
            ),
        ],
    ) -> None:
        """
        Test the combination of MinimalInclusive and MaximalExclusive constraints on Time type.

        Args:
          ConstrainedParameter: A Time parameter with a MinimalExclusive constraint of 08:00:00.500-02:30 and a
            MaximalInclusive constraint of 18:59:59.595+02:30
        """

    # Timestamp type constraints

    @sila.UnobservableCommand()
    async def check_timestamp_constraint_set(
        self,
        constrained_parameter: typing.Annotated[
            datetime.datetime,
            sila.constraints.Set(
                [
                    datetime.datetime(1969, 7, 16, 13, 32, 00, 1000),
                    datetime.datetime(1969, 7, 20, 20, 17, 40),
                    datetime.datetime(1969, 7, 24, 16, 50, 35, 123000),
                ]
            ),
        ],
    ) -> None:
        """
        Test the Set constraint on the Timestamp type.

        Args:
          ConstrainedParameter: A Timestamp parameter with a Set constraint of 1969-07-16T13:32:00.001Z,
            1969-07-20T20:17:40Z, 1969-07-24T16:50:35.123+00:00
        """

    @sila.UnobservableCommand()
    async def check_timestamp_constraint_maximal_exclusive(
        self,
        constrained_parameter: typing.Annotated[
            datetime.datetime,
            sila.constraints.MaximalExclusive(
                datetime.datetime(2022, 9, 7, 16, 0, 0, 0, tzinfo=datetime.timezone(datetime.timedelta(hours=2)))
            ),
        ],
    ) -> None:
        """
        Test the MaximalExclusive constraint on the Timestamp type.

        Args:
          ConstrainedParameter: A Timestamp parameter with a MaximalExclusive constraint of
            2022-09-07T16:00:00.000+02:00
        """

    @sila.UnobservableCommand()
    async def check_timestamp_constraint_maximal_inclusive(
        self,
        constrained_parameter: typing.Annotated[
            datetime.datetime,
            sila.constraints.MaximalInclusive(
                datetime.datetime(
                    2025, 12, 31, 13, 59, 59, 999000, tzinfo=datetime.timezone(datetime.timedelta(hours=-2, minutes=30))
                )
            ),
        ],
    ) -> None:
        """
        Test the MaximalInclusive constraint on the Timestamp type.

        Args:
          ConstrainedParameter: A Timestamp parameter with a MaximalInclusive constraint of
            2025-12-31T13:59:59.999-01:30
        """

    @sila.UnobservableCommand()
    async def check_timestamp_constraint_minimal_exclusive(
        self,
        constrained_parameter: typing.Annotated[
            datetime.datetime,
            sila.constraints.MinimalExclusive(
                datetime.datetime(2019, 1, 1, 0, 0, 0, 0, tzinfo=datetime.timezone(datetime.timedelta(hours=-1)))
            ),
        ],
    ) -> None:
        """
        Test the MinimalExclusive constraint on the Timestamp type.

        Args:
          ConstrainedParameter: A Timestamp parameter with a MinimalExclusive constraint of 2019-01-01T00:00:00-01:00
        """

    @sila.UnobservableCommand()
    async def check_timestamp_constraint_minimal_inclusive(
        self,
        constrained_parameter: typing.Annotated[
            datetime.datetime,
            sila.constraints.MinimalInclusive(
                datetime.datetime(
                    2022, 9, 7, 13, 48, 59, 666000, tzinfo=datetime.timezone(datetime.timedelta(hours=2, minutes=0))
                )
            ),
        ],
    ) -> None:
        """
        Test the MinimalInclusive constraint on the Timestamp type.

        Args:
          ConstrainedParameter: A Timestamp parameter with a MinimalInclusive constraint of
            2022-09-07T13:48:59.666+02:00
        """

    @sila.UnobservableCommand()
    async def check_timestamp_constraint_minmax(
        self,
        constrained_parameter: typing.Annotated[
            datetime.datetime,
            sila.constraints.MinimalExclusive(datetime.datetime(1969, 7, 20, 20, 17, 40, 303000)),
            sila.constraints.MaximalInclusive(datetime.datetime(1972, 12, 11, 19, 54, 57, 59000)),
        ],
    ) -> None:
        """
        Test the combination of MinimalInclusive and MaximalExclusive constraints on Timestamp type.

        Args:
          ConstrainedParameter: A Timestamp parameter with a MinimalInclusive constraint of 1969-07-20T20:17:40.303Z and
            a MaximalExclusive constraint of 1972-12-11T19:54:57.059Z
        """

    # List type constraints

    @sila.UnobservableCommand()
    async def check_list_constraint_element_count(
        self,
        constrained_parameter: typing.Annotated[list[str], sila.constraints.ElementCount(5)],
    ) -> None:
        """
        Test the ElementCount constraint on the List type.

        Args:
          ConstrainedParameter: A String List parameter with an ElementCount constraint of 5
        """

    @sila.UnobservableCommand()
    async def check_list_constraint_minimal_element_count(
        self,
        constrained_parameter: typing.Annotated[list[str], sila.constraints.MinimalElementCount(3)],
    ) -> None:
        """
        Test the MinimalElementCount constraint on the List type.

        Args:
          ConstrainedParameter: A String List parameter with an MinimalElementCount constraint of 3
        """

    @sila.UnobservableCommand()
    async def check_list_constraint_maximal_element_count(
        self,
        constrained_parameter: typing.Annotated[list[str], sila.constraints.MaximalElementCount(5)],
    ) -> None:
        """
        Test the MaximalElementCount constraint on the List type.

        Args:
          ConstrainedParameter: A String List parameter with an MaximalElementCount constraint of 5
        """

    @sila.UnobservableCommand()
    async def check_list_constraint_minmax_element_count(
        self,
        constrained_parameter: typing.Annotated[
            list[str], sila.constraints.MinimalElementCount(2), sila.constraints.MaximalElementCount(5)
        ],
    ) -> None:
        """
        Test the combination of MinimalElementCount and MaximalElementCount constraints on the List type.

        Args:
          ConstrainedParameter: A String List parameter with a MinimalElementCount constraint of 2 and
            a MaximalElementCount constraint of 5
        """

    # Binary type constraints

    @sila.UnobservableCommand()
    async def check_binary_constraint_length(
        self,
        constrained_parameter: typing.Annotated[bytes, sila.constraints.Length(10)],
    ) -> None:
        """
        Test the Length constraint on the Binary type.

        Args:
          ConstrainedParameter: A Binary parameter with a Length constraint of 10
        """

    @sila.UnobservableCommand()
    async def check_binary_constraint_minimal_length(
        self,
        constrained_parameter: typing.Annotated[bytes, sila.constraints.MinimalLength(5)],
    ) -> None:
        """
        Test the MinimalLength constraint on the Binary type.

        Args:
          ConstrainedParameter: A Binary parameter with a MinimalLength constraint of 5
        """

    @sila.UnobservableCommand()
    async def check_binary_constraint_maximal_length(
        self,
        constrained_parameter: typing.Annotated[bytes, sila.constraints.MaximalLength(20)],
    ) -> None:
        """
        Test the MaximalLength constraint on the Binary type.

        Args:
          ConstrainedParameter: A Binary parameter with a MaximalLength constraint of 20
        """

    @sila.UnobservableCommand()
    async def check_binary_constraint_minmax_length(
        self,
        constrained_parameter: typing.Annotated[
            bytes, sila.constraints.MinimalLength(5), sila.constraints.MaximalLength(20)
        ],
    ) -> None:
        """
        Test the combination of MinimalLength and MaximalLength constraints on the Binary type.

        Args:
          ConstrainedParameter: A Binary parameter with a MinimalLength constraint of 5 and
            a MaximalLength constraint of 20
        """

    @sila.UnobservableCommand()
    async def check_binary_constraint_content_type(
        self,
        constrained_parameter: typing.Annotated[bytes, sila.constraints.ContentType("application", "xml")],
    ) -> None:
        """
        Test the ContentType constraint on the Binary type.

        Args:
          ConstrainedParameter: A Binary parameter with a ContentType constraint allowing
            only valid XML document as content
        """

    @sila.UnobservableCommand()
    async def check_binary_constraint_schema(
        self,
        constrained_parameter: typing.Annotated[
            bytes,
            sila.constraints.Schema(
                "Xml",
                url="https://gitlab.com/SiLA2/sila_base/-/raw/master/schema/FeatureDefinition.xsd",
            ),
        ],
    ) -> None:
        """
        Test that the parameter is valid for a given Schema constraint.

        Args:
          ConstrainedParameter: A Binary parameter with a Schema constraint allowing only content that is
            compliant with the SiLA 2 Feature Definition schema
        """

    # Any type constraints

    @sila.UnobservableCommand()
    async def check_allowed_types_constraint(
        self,
        constrained_parameter: typing.Annotated[
            Native,
            sila.constraints.AllowedTypes(
                [sila.data_types.Integer, sila.data_types.List.create(sila.data_types.Integer)]
            ),
        ],
    ) -> None:
        """
        Test the AllowedTypes constraint on the Any type.

        Args:
          ConstrainedParameter: An Any type parameter with an AllowedTypes constraint that only
            allows an integer or a list of integers
        """

    @sila.UnobservableCommand()
    async def check_allowed_structure_type_constraints(
        self,
        constrained_parameter: typing.Annotated[
            Native,
            sila.constraints.AllowedTypes(
                [
                    sila.data_types.Structure.create(
                        {"item": sila.data_types.Element("Item", "Item", "The actual item", sila.data_types.Integer)}
                    )
                ]
            ),
        ],
    ) -> None:
        """
        Test the AllowedTypes constraint with a Structure type on the Any type.

        Args:
          ConstrainedParameter: An Any type parameter with an AllowedTypes constraint that
            only allows a structure with an integer
        """
