import os
from dataclasses import dataclass
from typing import Sequence


@dataclass(frozen=True)
class AlembicDatabaseInfo(object):
    name: str
    conn_strings: Sequence[str]
    alembic_path: str
    versions_dir: str

    def __init__(self, name: str, conn_strings: Sequence[str]):
        object.__setattr__(self, "name", name)
        object.__setattr__(self, "conn_strings", conn_strings)
        object.__setattr__(self, "alembic_path", self._get_alembic_path())
        object.__setattr__(self, "versions_dir", self._get_version_dir())

    def _get_alembic_path(self) -> str:
        return self._get_parent_alembic_path(os.path.abspath(__file__))

    def _get_version_dir(self):
        name_dir = os.path.join(self.alembic_path, self.name)
        if os.path.isdir(name_dir):
            return name_dir
        return os.path.join(self.alembic_path, "versions")

    def _get_parent_alembic_path(self, current_dir) -> str:
        alembic_path = os.path.join(current_dir, "alembic")
        if self._is_valid_alembic_dir(alembic_path=alembic_path):
            return alembic_path
        parent_dir = os.path.dirname(current_dir)
        if parent_dir == current_dir:
            raise RuntimeError("Could not find alembic path")
        return self._get_parent_alembic_path(parent_dir)

    @staticmethod
    def _is_valid_alembic_dir(alembic_path):
        if not os.path.exists(alembic_path) or not os.path.isdir(alembic_path):
            return False

        alembic_ini = os.path.join(alembic_path, "alembic.ini")
        return os.path.exists(alembic_ini) and os.path.isfile(alembic_ini)
