from dataclasses import dataclass, field
from typing import Dict, Set, Optional, List

from ._SchemaModel import SchemaModel
from ._SchemaPropertyTypeEnum import SchemaPropertyTypeEnum
from ..utils import set_dict_path_value


@dataclass
class ObjectSchemaModel(SchemaModel):
    properties: Dict[str, SchemaModel] = None
    required: Set[str] = field(default_factory=set)

    def add_property(self, name: str, prop: SchemaModel, required: bool = True) -> None:
        if self.properties is None:
            self.properties = {}

        set_dict_path_value(dict_value=self.properties, path=[name], value=prop)

        if required:
            self.required.add(name)
        elif name in self.required:
            self.required.remove(name)

    def to_dict(self) -> dict:
        return {
            "type": SchemaPropertyTypeEnum.object,
            **super().to_dict(),
            "required": self._get_required_properties(),
        }

    def _get_required_properties(self) -> Optional[List[str]]:
        if self.properties is None:
            return None

        ret = []
        for prop in self.properties.keys():
            if prop in self.required:
                ret.append(prop)

        return ret
