from dataclasses import dataclass
from typing import (
    Optional,
    Sequence,
)


@dataclass(frozen=True)
class DatabaseInfo(object):
    conn_string_template = "file:${DB_NAME}?mode=memory&cache=shared"

    name: str
    number_of_instances: Optional[int]

    def __init__(self, name, number_of_instances: Optional[int] = None):
        object.__setattr__(self, "name", name)
        object.__setattr__(self, "number_of_instances", number_of_instances)

    @property
    def conn_string(self):
        return self._format_conn_string()

    @property
    def all_conn_strings(self) -> Sequence[str]:
        if self.number_of_instances is None:
            return [self.conn_string]
        else:
            return [self._format_conn_string(instance_number=i) for i in range(self.number_of_instances + 1)]

    @property
    def all_db_names(self) -> Sequence[str]:
        if self.number_of_instances is None:
            return [self.name]
        else:
            return [self._get_db_name(instance_number=i) for i in range(self.number_of_instances + 1)]

    def get_conn_string_dict(self):
        return {db_name: conn_string for db_name, conn_string in zip(self.all_db_names, self.all_conn_strings)}

    def _format_conn_string(self, instance_number: int = None):
        if self.number_of_instances is None:
            return self.conn_string_template.replace("${DB_NAME}", self.name)
        return self.conn_string_template.replace("${DB_NAME}", self._get_db_name(instance_number=instance_number))

    def _get_db_name(self, instance_number: int = None):
        return f"{self.name}{instance_number}"
