from dataclasses import dataclass, field
from typing import List, Dict, Union

from ._BaseModel import BaseModel
from ._PathParameterModel import PathParameterModel
from ._PathResponseModel import PathResponseModel
from ._RequestBodyModel import RequestBodyModel
from ..utils import set_dict_path_value


@dataclass
class PathModel(BaseModel):
    responses: Dict[str, PathResponseModel] = field(default_factory=dict)
    parameters: List[PathParameterModel] = field(default_factory=list)
    request_body: RequestBodyModel = None
    summary: str = None
    tags: List[str] = field(default_factory=list)
    description: str = None

    _parameters_dict: Dict[str, Dict] = field(default_factory=dict)

    def add_parameter(self, parameter: PathParameterModel) -> None:
        if not self.has_parameter(parameter.name):
            self._parameters_dict[parameter.name] = {
                'parameter': parameter,
                'index': len(self.parameters),
            }
            self.parameters.append(parameter)
        else:
            param_def = self._parameters_dict[parameter.name]
            param_def['parameter'] = parameter
            self.parameters[param_def['index']] = parameter

    def has_parameter(self, name: str) -> bool:
        return name in self._parameters_dict

    def add_response(self, code: Union[int, str], response: PathResponseModel) -> None:
        if self.responses is None:
            self.responses = {}

        set_dict_path_value(
            dict_value=self.responses,
            path=[str(code)],
            value=response
        )
