"""§22.13 step 1 — the bootstrap-id re-stamp: 'default' → the configured
DEFAULT_PROJECT_ID. §22 three-tier (S1): the entry-corpus tables key on
collection_id now, so the re-stamp renames the *project grain* — the
`collections.project_id` link and the denormalised project_id tags — while the
entries stay in their collection. The stale 'default' projects row is dropped,
the composite FKs stay intact, and it is idempotent."""
from __future__ import annotations

import tempfile
from pathlib import Path

import app.db as db
from app import projects


class _Cfg:
    def __init__(self, path, default_id):
        self.database_path = path
        self.default_project_id = default_id


def _setup(monkeypatch, default_id="ohm"):
    path = str(Path(tempfile.mkdtemp()) / "t.db")
    cfg = _Cfg(path, default_id)
    db.run_migrations(cfg)  # seeds the bootstrap 'default' project + its default collection
    monkeypatch.setattr(db, "_CONN", db.connect(path))
    conn = db.conn()
    # A registry-mirrored 'ohm' project coexists with the bootstrap pre-restamp.
    conn.execute("INSERT OR IGNORE INTO projects (id,name,content_repo,visibility) "
                 "VALUES ('ohm','Open Human Model','ohm-content','public')")
    conn.execute("INSERT INTO users (id,gitea_login,display_name,role) VALUES (1,'a','A','contributor')")
    # Entry data lives in the default collection (id='default'); the entry grain
    # is the collection and does not move on a re-stamp.
    conn.execute("INSERT INTO cached_rfcs (slug,title,state,collection_id) VALUES ('human','Human','active','default')")
    conn.execute("INSERT INTO rfc_collaborators (rfc_slug,user_id,role_in_rfc,collection_id) "
                 "VALUES ('human',1,'contributor','default')")
    conn.execute("INSERT INTO stars (user_id,rfc_slug,collection_id) VALUES (1,'human','default')")
    return cfg, conn


def test_restamp_moves_project_grain_and_drops_bootstrap_row(monkeypatch):
    cfg, conn = _setup(monkeypatch, default_id="ohm")
    projects.restamp_default_project(cfg)
    # The project grain (the collection's parent link) re-stamps to 'ohm'.
    assert conn.execute("SELECT COUNT(*) c FROM collections WHERE project_id='default'").fetchone()["c"] == 0
    assert conn.execute("SELECT project_id FROM collections WHERE id='default'").fetchone()["project_id"] == "ohm"
    # Entries stay in their collection — the collection_id is unchanged.
    assert conn.execute("SELECT collection_id FROM cached_rfcs WHERE slug='human'").fetchone()["collection_id"] == "default"
    assert conn.execute("SELECT collection_id FROM rfc_collaborators WHERE rfc_slug='human'").fetchone()["collection_id"] == "default"
    # stale bootstrap projects row removed; 'ohm' remains
    assert conn.execute("SELECT 1 FROM projects WHERE id='default'").fetchone() is None
    assert conn.execute("SELECT 1 FROM projects WHERE id='ohm'").fetchone() is not None
    # FK integrity intact after the rename
    assert conn.execute("PRAGMA foreign_key_check").fetchall() == []


def test_restamp_is_idempotent(monkeypatch):
    cfg, conn = _setup(monkeypatch, default_id="ohm")
    projects.restamp_default_project(cfg)
    projects.restamp_default_project(cfg)  # second call: no bootstrap rows left → no-op
    assert conn.execute("SELECT project_id FROM collections WHERE id='default'").fetchone()["project_id"] == "ohm"
    assert conn.execute("SELECT COUNT(*) c FROM cached_rfcs WHERE collection_id='default'").fetchone()["c"] == 1


def test_restamp_noop_when_default_id_unchanged(monkeypatch):
    cfg, conn = _setup(monkeypatch, default_id="")  # resolves to 'default'
    projects.restamp_default_project(cfg)
    # nothing renamed; the default collection still belongs to the bootstrap project
    assert conn.execute("SELECT project_id FROM collections WHERE id='default'").fetchone()["project_id"] == "default"
