from abc import ABC
from dataclasses import fields

from ..utils import to_camel_case


class BaseModel(ABC):

    def set(self, **kwargs) -> 'BaseModel':
        valid = {f.name for f in fields(self)}
        for key, value in kwargs.items():
            if key not in valid:
                raise AttributeError(f"Unknown field: {key}")
            setattr(self, key, value)
        return self

    def to_dict(self) -> dict:
        ret = {}
        for k, v in self.__dict__.items():
            if not k.startswith("_"):
                ret[self.get_field_key(k)] = v
        return ret

    def get_field_key(self, field_name: str) -> str:
        return to_camel_case(field_name)

    @staticmethod
    def _is_empty(value) -> bool:
        return value is None or (hasattr(value, '__len__') and len(value or []) == 0)

    def get_model_data(self) -> dict:
        return {k: v for k, v in self.to_dict().items() if not self._is_empty(v)}
