#  Copyright (C) 2025
#  ABM, Moscow
#
#  UNPUBLISHED PROPRIETARY MATERIAL.
#  ALL RIGHTS RESERVED.
#
#  Authors: Mike Orlov <m.orlov@abm-jsc.ru>
import functools
from dataclasses import dataclass
from typing import Iterable, Mapping

from frozendict import frozendict
from init_helpers import AnyType, Jsonable
from more_itertools import first

from .example import BaseExample
from .schema import BaseSchema
from .spec_ref import SpecRef
from .spec_resource import SpecResource


@dataclass(frozen=True, slots=True)
class MediaType(SpecResource):
    schema: AnyType | BaseSchema
    examples: Iterable[BaseExample] = tuple()
    # encoding: Mapping[str, EncodingObject] = field(default_factory=frozendict) todo: implement encoding

    def __post_init__(self):
        object.__setattr__(self, 'examples', tuple(self.examples))

    def get_spec_dependencies(self) -> frozenset['SpecResource']:
        return frozenset({self.schema} | set(self.examples))

    def get_spec_dict(self, dependency_to_ref: Mapping['SpecResource', SpecRef]) -> frozendict[str, Jsonable]:
        result = {'schema': dependency_to_ref[self.schema]}
        if self.examples:
            result['example'] = dependency_to_ref[first(self.examples)]
        return frozendict(result)

    @functools.cache
    def _get_repr_parts(self) -> tuple[str, ...]:
        result = [f'{self.schema!r}']
        result += [f'examples={self.examples!r}'] if self.examples else []
        return tuple(result)

    def __repr__(self):
        return f'{self.__class__.__name__}({", ".join(self._get_repr_parts())})'

    __str__ = __repr__
