"""Bolt adapter — works with any Bolt-compatible DB: Neo4j, Memgraph, ArcadeDB."""

from __future__ import annotations

from neo4j import GraphDatabase

from . import CypherAdapter, QueryResult


class BoltAdapter(CypherAdapter):
    """Works with any Bolt-compatible DB: Neo4j, Memgraph, ArcadeDB."""

    def connect(self, host, port, auth, **options):
        uri = f"bolt://{host}:{port}"
        self._driver = GraphDatabase.driver(
            uri,
            auth=(auth.get("username", ""), auth.get("password", "")),
            connection_timeout=5,
            max_transaction_retry_time=0,
        )
        self._db = options.get("database_name")
        # Eagerly verify connectivity so we fail fast instead of hanging
        self._driver.verify_connectivity()

    def execute(self, query):
        records, summary, keys = self._driver.execute_query(
            query, database_=self._db
        )
        return QueryResult(
            columns=list(keys),
            rows=[[record[k] for k in keys] for record in records],
        )

    def get_version(self) -> str | None:
        try:
            result = self.execute(
                "CALL dbms.components() YIELD name, versions"
            )
            return f"{result.rows[0][0]}/{result.rows[0][1][0]}"
        except Exception:
            return None

    def close(self):
        self._driver.close()
