from yta_editor_time.enum import SpecificationRequirement
from yta_editor_time.specifications.types import TimeMoment, TimeDuration
from dataclasses import dataclass
from typing import Union

    
@dataclass(frozen = True)
class TimeSpecification:
    """
    The time range of the element that must be affected
    according to this specification.

    TODO: Explain like the others
    """

    # TODO: By now we are not implementing the 'anchor'
    # because it complicates the logic a lot...
    # anchor: Anchor
    # """
    # The position, element or part of it to which this
    # specification is anchored.
    # """
    start_t: Union[TimeMoment, None]
    """
    The first time moment that must be affected by this
    specification.
    """
    end_t: Union[TimeMoment, None]
    """
    The last time moment that must be affected by this
    specification.
    """
    duration: Union[TimeDuration, None]
    """
    The total duration that this specification must
    last.
    """

    @property
    def requirements(
        self
    ) -> dict[SpecificationRequirement]:
        """
        The requirements of this specification that are
        needed to be able to resolve it.
        """
        return {
            SpecificationRequirement.FPS
        }

    def __post_init__(
        self
    ):
        # Normalize enums
        # object.__setattr__(self, 'anchor', Anchor.to_enum(self.anchor))

        # exactly two of three must be provided
        provided = sum(
            x is not None
            for x in (self.start_t, self.end_t, self.duration)
        )

        if provided != 2:
            raise ValueError(
                'Provide exactly two of: start_t, end_t, duration'
            )

        if (
            self.start_t and
            self.end_t
        ):
            if self.end_t.value < self.start_t.value:
                raise ValueError('end_t must be >= start_t')

        if (
            self.duration and
            self.duration.value == 0
        ):
            raise ValueError('duration must be > 0')