#!/usr/bin/env python3
"""
migrate_backlog_postgres.py — Idempotent DDL migration for Engineering Backlog.
DAARION.city

Creates tables and indexes if they do not exist. Safe to re-run.

Usage:
  python3 ops/scripts/migrate_backlog_postgres.py
  python3 ops/scripts/migrate_backlog_postgres.py --dry-run
  python3 ops/scripts/migrate_backlog_postgres.py --dsn "postgresql://user:pass@host/db"
"""
from __future__ import annotations

import argparse
import os
import sys

DDL = [
    # ── backlog_items ─────────────────────────────────────────────────────────
    """
    CREATE TABLE IF NOT EXISTS backlog_items (
        id              TEXT        PRIMARY KEY,
        created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW(),
        updated_at      TIMESTAMPTZ NOT NULL DEFAULT NOW(),
        env             TEXT        NOT NULL DEFAULT 'prod',
        service         TEXT        NOT NULL DEFAULT '',
        category        TEXT        NOT NULL DEFAULT '',
        title           TEXT        NOT NULL DEFAULT '',
        description     TEXT        NOT NULL DEFAULT '',
        priority        TEXT        NOT NULL DEFAULT 'P2',
        status          TEXT        NOT NULL DEFAULT 'open',
        owner           TEXT        NOT NULL DEFAULT 'oncall',
        due_date        DATE,
        source          TEXT        NOT NULL DEFAULT 'manual',
        dedupe_key      TEXT        NOT NULL UNIQUE DEFAULT '',
        evidence_refs   JSONB       NOT NULL DEFAULT '{}',
        tags            JSONB       NOT NULL DEFAULT '[]',
        meta            JSONB       NOT NULL DEFAULT '{}'
    )
    """,
    # ── backlog_events ────────────────────────────────────────────────────────
    """
    CREATE TABLE IF NOT EXISTS backlog_events (
        id              TEXT        PRIMARY KEY,
        item_id         TEXT        NOT NULL REFERENCES backlog_items(id) ON DELETE CASCADE,
        ts              TIMESTAMPTZ NOT NULL DEFAULT NOW(),
        type            TEXT        NOT NULL DEFAULT 'comment',
        message         TEXT        NOT NULL DEFAULT '',
        actor           TEXT        NOT NULL DEFAULT 'system',
        meta            JSONB       NOT NULL DEFAULT '{}'
    )
    """,
    # ── Indexes ───────────────────────────────────────────────────────────────
    "CREATE INDEX IF NOT EXISTS idx_backlog_items_env_status   ON backlog_items (env, status)",
    "CREATE INDEX IF NOT EXISTS idx_backlog_items_service       ON backlog_items (service)",
    "CREATE INDEX IF NOT EXISTS idx_backlog_items_due_date      ON backlog_items (due_date)",
    "CREATE INDEX IF NOT EXISTS idx_backlog_items_owner         ON backlog_items (owner)",
    "CREATE INDEX IF NOT EXISTS idx_backlog_items_category      ON backlog_items (category)",
    "CREATE INDEX IF NOT EXISTS idx_backlog_events_item_id      ON backlog_events (item_id)",
    "CREATE INDEX IF NOT EXISTS idx_backlog_events_ts           ON backlog_events (ts)",
]


def migrate(dsn: str, dry_run: bool = False) -> None:
    print(f"[backlog migration] DSN: {dsn!r}  dry_run={dry_run}")
    if dry_run:
        print("[dry-run] Would execute the following DDL statements:")
        for stmt in DDL:
            print("  ", stmt.strip()[:120])
        return

    try:
        import psycopg2
    except ImportError:
        print("ERROR: psycopg2 not installed. Run: pip install psycopg2-binary", file=sys.stderr)
        sys.exit(1)

    conn = psycopg2.connect(dsn)
    conn.autocommit = True
    try:
        with conn.cursor() as cur:
            for stmt in DDL:
                stmt = stmt.strip()
                if not stmt:
                    continue
                print(f"  EXEC: {stmt[:80].replace(chr(10), ' ')}…")
                cur.execute(stmt)
        print("[backlog migration] Done. All DDL applied idempotently.")
    finally:
        conn.close()


def main() -> None:
    parser = argparse.ArgumentParser(
        description="Idempotent Postgres DDL migration for Engineering Backlog"
    )
    parser.add_argument(
        "--dsn",
        default=os.environ.get(
            "BACKLOG_POSTGRES_DSN",
            os.environ.get("POSTGRES_DSN", "postgresql://localhost/daarion"),
        ),
        help="Postgres DSN (default: $BACKLOG_POSTGRES_DSN or $POSTGRES_DSN)",
    )
    parser.add_argument(
        "--dry-run",
        action="store_true",
        help="Print DDL without executing",
    )
    args = parser.parse_args()
    migrate(args.dsn, dry_run=args.dry_run)


if __name__ == "__main__":
    main()
