from dataclasses import dataclass
from functools import cached_property

from sqlalchemy import inspect


@dataclass
class Parser:
    data: dict

    @property
    def object_type(self):
        raise NotImplementedError()

    @cached_property
    def description(self):
        def add_one_entry(entry):
            desc = ""
            if type(entry) == str:
                desc += entry
            elif type(entry) == dict:
                if entry["type"] == "entries":
                    if "name" in entry:
                        desc += f"\n{entry['name']}\n"
                    for subentry in entry["entries"]:
                        desc += add_one_entry(subentry)
                else:
                    desc += f"\n[UNSUPPORTED ENTRY TYPE: {entry['type']}"
            return desc

        return "\n".join([add_one_entry(entry) for entry in self.data.get("entries", [])])

    @property
    def requires_attunement(self):
        return True if self.data.get("reqAttune", None) else False

    def parse(self):
        params = {}
        mapped = inspect(self.object_type)
        for col in mapped.columns.keys():
            val = getattr(self, col, None)
            if val:
                params[col] = val
        return self.object_type(**params)

    def __getattr__(self, attr_name):
        try:
            return self.data[attr_name]
        except KeyError:
            raise AttributeError()
