import uuid
from abc import ABC
from dataclasses import dataclass, field
from typing import Optional, Callable, Union

from ._BaseModel import BaseModel


@dataclass
class SchemaModel(BaseModel, ABC):
    description: Optional[str] = field(init=False, default=None)

    def set_schema_name(self, schema_name: Union[str, Callable[["SchemaModel"], str]]):
        setattr(self, '_schema_name', schema_name)

    def get_schema_name(self) -> str:
        _schema_name = getattr(self, '_schema_name', None)
        if _schema_name is None:
            return self.get_schema_uuid()

        if isinstance(_schema_name, Callable):
            return _schema_name(self)
        return _schema_name

    def set_schema_uuid(self, schema_uuid: Union[str, Callable[["SchemaModel"], str]]):
        setattr(self, '_schema_uuid', schema_uuid)

    def get_schema_uuid(self) -> str:
        _schema_uuid = getattr(self, '_schema_uuid', None)
        if _schema_uuid is None:
            return str(uuid.uuid4())
        if isinstance(_schema_uuid, Callable):
            return _schema_uuid(self)
        return _schema_uuid
