"""
cortex/hippo/db/migration.py — Schema migration runner for Hippo's separate DB.

Hippo uses its own database (hippo.db), separate from cortex.db.
This migration runner manages Hippo's schema independently.

Issue: #801
"""

from __future__ import annotations

import logging

import aiosqlite

from cortex.hippo.db.schema import (
    ALL_DDL,
    HIPPO_SCHEMA_VERSION,
)

logger = logging.getLogger(__name__)


async def get_hippo_schema_version(conn: aiosqlite.Connection) -> int:
    """Read the current Hippo schema version from hippo_config."""
    try:
        async with conn.execute(
            "SELECT value FROM hippo_config WHERE key = 'schema_version'"
        ) as cur:
            row = await cur.fetchone()
            return int(row[0]) if row else 0
    except Exception:
        return 0


async def apply_hippo_schema(conn: aiosqlite.Connection) -> int:
    """Apply the Hippo schema (create tables if they don't exist).

    Returns the schema version after application.
    This is idempotent — safe to call on every startup.
    """
    current = await get_hippo_schema_version(conn)

    if current >= HIPPO_SCHEMA_VERSION:
        logger.debug("Hippo schema up to date (v%d)", current)
        return current

    logger.info(
        "Applying Hippo schema v%d (current: v%d)",
        HIPPO_SCHEMA_VERSION,
        current,
    )

    for ddl in ALL_DDL:
        ddl = ddl.strip()
        if not ddl:
            continue
        try:
            await conn.executescript(ddl)
        except Exception as exc:
            if "fts5" in ddl.lower() or "trigger" in ddl.lower():
                logger.warning("FTS/trigger creation skipped: %s", exc)
            else:
                raise

    # Store schema version
    await conn.execute(
        """
        INSERT INTO hippo_config (key, value, updated_at)
        VALUES ('schema_version', ?, strftime('%Y-%m-%dT%H:%M:%SZ', 'now'))
        ON CONFLICT(key) DO UPDATE SET
            value = excluded.value,
            updated_at = excluded.updated_at
        """,
        (str(HIPPO_SCHEMA_VERSION),),
    )
    await conn.commit()

    logger.info("Hippo schema applied successfully (v%d)", HIPPO_SCHEMA_VERSION)
    return HIPPO_SCHEMA_VERSION
