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

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

from .parameter import ParameterStyle
from .spec_resource import SpecResource
from .spec_ref import SpecRef


@dataclass(frozen=True, slots=True)
class BodyPartDescription(SpecResource):
    content_type: ContentType | tuple[ContentType, ...] | None = None
    headers: Mapping[str, Annotated | type] | None = None
    style: ParameterStyle | None = None
    explode: bool | None = None

    def __init__(
            self,
            content_type: ContentType | Iterable[ContentType] | None = None,
            headers: dict[str, Annotated] | None = None,
            style: ParameterStyle | None = None,
            explode: bool | None = None,
    ) -> None:
        object.__setattr__(
            self, 'content_type',
            content_type if content_type is None or isinstance(content_type, ContentType) else tuple(content_type))
        object.__setattr__(self, 'headers', frozendict(headers) if headers else None)
        object.__setattr__(self, 'style', style)
        object.__setattr__(self, 'explode', explode)

    def get_spec_dependencies(self) -> frozenset['SpecResource']:
        return frozenset(self.headers.values()) if self.headers else frozendict()

    def get_spec_dict(self, dependency_to_ref: Mapping['SpecResource', SpecRef]) -> frozendict[str, Jsonable]:
        description = {}
        if self.explode is not None:
            description["explode"] = self.explode
        if self.style is not None:
            description["style"] = self.style
        if self.content_type:
            description["content_type"] = ", ".join(self.content_type)
        if self.headers:
            description["headers"] = {k: dependency_to_ref[v] for k, v in self.headers.items()}

        return frozendict(description)
