"Vanilla common values and exceptions."

from collections.abc import Callable
import sqlite3 as sql3

SqliteType = None | int | float | str | bytes
"A type that sqlite natively understands."

# TODO: why no doc?
type RowFactory[Result] = Callable[[sql3.Cursor, tuple[SqliteType, ...]], Result]
"""A `RowFactory <https://docs.python.org/3/library/sqlite3.html#how-to-create-and-use-row-factories>`
"""


class CoolqliteError(Exception):
    "A base exception for all standard coolqlite errors."

    pass


class CoolqliteWarning(CoolqliteError, UserWarning):
    pass


class InternalCoolqliteError(CoolqliteError):
    def __new__(cls, msg: str = ""):  # pragma: no cover
        msg = f"YOU SHOULD NEVER SEE THIS I'M SORRY\nPlease file a ticket.\n{msg}"
        return super().__new__(cls, msg)


class CoolqliteExceptionGroup[E: Exception = Exception](
    ExceptionGroup[E], CoolqliteError
):
    "A base exceptiongroup for all standard coolqlite errors."

    pass


# TODO: a proper unified error handling philosophy,
# including thinking about how it works with cattrs.


class MissingNamedToSqlFnError(CoolqliteError):
    "A named adapter was missing."

    def __init__(self, name: str):
        super().__init__(f"Missing adapter named {name}")
        self.add_note("Did you forget to register it, or disable a default?")


class MissingTypedToSqlFnError(CoolqliteError):
    "A value was given of a type the converter didn't know how to handle."

    pass


# TODO: base type and make its subclasses final?
# is that possible like in kotlin?
type MissingToSqlFnError = MissingTypedToSqlFnError | MissingNamedToSqlFnError
"Some sort of ToSql converter was missing."


class ToSqlFnSetupError(CoolqliteError):
    "An error occurred while setting up a tosql function."

    pass


class CoolqliteTypeError(CoolqliteError, TypeError):
    "A type error."

    pass


class ToSqlTypeError(CoolqliteTypeError):
    "A type error related to converting to sql."

    pass


class ToSqlValueError(CoolqliteError, ValueError):
    "A value error related to converting to sql."

    pass


class FromSqlTypeError(CoolqliteTypeError):
    "A type error related to converting from sql."

    pass


_DONT_INIT_YOURSELF_OR_THINGS_WILL_BREAK = object()
