#  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, field
from typing import ClassVar, Mapping

from frozendict import frozendict
from http_tools import ContentType
from init_helpers import Jsonable

from .spec_resource import SpecResource
from .spec_ref import SpecRef
from .maybe_referencable_resource import MaybeReferencableResource
from .media_type import MediaType


@dataclass(frozen=True, slots=True)
class Response(MaybeReferencableResource):
    spec_path: ClassVar[list[str]] = ['components', 'responses']
    description: str = ''
    # headers: Mapping[str, str] = field(default_factory=frozendict)  # todo: implement headers
    content_type_to_media_type: Mapping[ContentType, MediaType] = field(default_factory=frozendict)
    # links: Mapping[str, Link]  # todo: implement links
    key: str | None = field(default=None, kw_only=True)

    def __post_init__(self):
        object.__setattr__(self, 'content_type_to_media_type', frozendict(self.content_type_to_media_type))

    def get_key(self) -> str:
        return None
        return self.key

    def get_spec_dependencies(self) -> frozenset['SpecResource']:
        return frozenset(self.content_type_to_media_type.values())

    def get_spec_dict(self, dependency_to_ref: Mapping['SpecResource', SpecRef]) -> frozendict[str, Jsonable]:
        result = {"description": self.description}
        if self.content_type_to_media_type:
            result["content"] = {t: dependency_to_ref[s] for t, s in self.content_type_to_media_type.items()}

        return frozendict(result)

    @functools.cache
    def _get_repr_parts(self) -> tuple[str, ...]:
        result = ([repr({ct.value: mt for ct, mt in self.content_type_to_media_type.items()})]
                  if self.content_type_to_media_type else [])
        result += [f'key={self.key!r}'] if self.key else []
        result += [f'description={self.description!r}'] if self.description else []
        return tuple(result)

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

    __str__ = __repr__
