"""Movie domain value objects.""" import re from dataclasses import dataclass from enum import Enum from ..shared.exceptions import ValidationError class Quality(Enum): """Video quality levels.""" SD = "480p" HD = "720p" FULL_HD = "1080p" UHD_4K = "2160p" UNKNOWN = "unknown" @classmethod def from_string(cls, quality_str: str) -> "Quality": """ Parse quality from string. Args: quality_str: Quality string (e.g., "1080p", "720p") Returns: Quality enum value """ quality_map = { "480p": cls.SD, "720p": cls.HD, "1080p": cls.FULL_HD, "2160p": cls.UHD_4K, } return quality_map.get(quality_str, cls.UNKNOWN) @dataclass(frozen=True) class MovieTitle: """ Value object representing a movie title. Ensures the title is valid and normalized. """ value: str def __post_init__(self): """Validate movie title.""" if not self.value: raise ValidationError("Movie title cannot be empty") if not isinstance(self.value, str): raise ValidationError( f"Movie title must be a string, got {type(self.value)}" ) if len(self.value) > 500: raise ValidationError( f"Movie title too long: {len(self.value)} characters (max 500)" ) def normalized(self) -> str: """ Return normalized title for file system usage. Removes special characters and replaces spaces with dots. """ # Remove special characters except spaces, dots, and hyphens cleaned = re.sub(r"[^\w\s\.\-]", "", self.value) # Replace spaces with dots normalized = cleaned.replace(" ", ".") return normalized def __str__(self) -> str: return self.value def __repr__(self) -> str: return f"MovieTitle('{self.value}')" @dataclass(frozen=True) class ReleaseYear: """ Value object representing a movie release year. Validates that the year is reasonable. """ value: int def __post_init__(self): """Validate release year.""" if not isinstance(self.value, int): raise ValidationError( f"Release year must be an integer, got {type(self.value)}" ) # Movies started around 1888, and we shouldn't have movies from the future if self.value < 1888 or self.value > 2100: raise ValidationError(f"Invalid release year: {self.value}") def __str__(self) -> str: return str(self.value) def __repr__(self) -> str: return f"ReleaseYear({self.value})"