import sqlalchemy
from sqlalchemy import DDL, event

from openlog.core.trace_splitter import XplordbSplitTracesQueries
from openlog.datamodel.assay.generic_assay import (
    AssayColumn,
    AssayDatabaseDefinition,
    AssayDataExtent,
    AssayDefinition,
    AssayDomainType,
    AssaySeriesType,
)
from openlog.datamodel.connection.interfaces.categories_interface import (
    CategoriesInterface,
)
from openlog.datamodel.connection.sqlalchemy.sqlalchemy_assay_interface import (
    SqlAlchemyAssayInterface,
)


class XplordbAssayInterface(SqlAlchemyAssayInterface):
    def __init__(self, engine, session, categories_iface: CategoriesInterface):
        """
        Implement AssayInterface for a Xplordb db

        Args:
            engine: sqlalchemy engine
            session: sqlalchemy session created from engine
            categories_iface : CategoriesInterface to get default lith category name
        """
        self._categories_iface = categories_iface
        super().__init__(engine, session, "assay")
        self.trace_splitter = XplordbSplitTracesQueries

    def default_assay_schema(self) -> str:
        """
        Return default schema for assay table creation

        """
        return "assay"

    def _before_sqlalchemy_table_creation(
        self, table: sqlalchemy.Table, schema: str
    ) -> None:
        """
        Define sqlalchemy events before table creation. Used to define specific permission on created table.

        Args:
            base: sqlalchemy base to be created
            schema: (str) database schema used
        """
        schema_str = ""
        if schema:
            schema_str = schema + "."

        event.listen(
            table,
            "after_create",
            DDL(
                f"GRANT SELECT ON TABLE {schema_str}{table.name} TO xdb_viewer;"
                f"GRANT SELECT, UPDATE, INSERT ON TABLE {schema_str}{table.name} TO xdb_logger;"
                f"GRANT SELECT, UPDATE, INSERT ON TABLE {schema_str}{table.name} TO xdb_importer;"
                f"GRANT ALL ON TABLE {schema_str}{table.name} TO xdb_admin;"
            ),
        )
