"""G-15 — the §22 three-tier write-path resolver.

`projects.content_repo_for_collection` and `projects.entry_location` resolve an
entry's git location (org, content_repo, md_path) from its *collection*
(collection → project → content_repo, plus the collection subfolder) instead of
the deployment default. This is the keystone the branch/edit/body/graduation
write paths share so an entry outside the default project's default collection
reads/writes the correct file.
"""
from __future__ import annotations

import tempfile
from pathlib import Path

from app import collections as collections_mod, db, projects as projects_mod
from app.config import Config


def _db() -> Config:
    cfg = Config(
        gitea_url="x", gitea_bot_user="x", gitea_bot_token="x", gitea_org="wiggleverse",
        registry_repo="registry", oauth_client_id="x",
        oauth_client_secret="x", app_url="x", secret_key="x",
        database_path=Path(tempfile.mkdtemp(prefix="g15loc-")) / "t.db",
        owner_gitea_login="x", webhook_secret="x",
    )
    db.run_migrations(cfg)
    if db._CONN is not None:
        db._CONN.close()
        db._CONN = None
    db.init(cfg)
    return cfg


def _seed():
    # Default project (its content_repo is the deployment default) + a second
    # project with a DISTINCT content_repo, each with a default + a named
    # (subfolder) collection.
    db.conn().execute(
        "INSERT OR REPLACE INTO projects (id, name, content_repo, visibility, updated_at) "
        "VALUES ('default','Default','meta','public', datetime('now'))")
    db.conn().execute(
        "INSERT OR REPLACE INTO projects (id, name, content_repo, visibility, updated_at) "
        "VALUES ('rfc-app','RFC App','rfc-app-content','public', datetime('now'))")
    rows = [
        ("default", "default", ""),
        ("features", "default", "features"),
        ("rfc-app", "rfc-app", ""),
        ("specs", "rfc-app", "specs"),
    ]
    for cid, pid, sub in rows:
        db.conn().execute(
            "INSERT OR REPLACE INTO collections (id, project_id, type, subfolder, "
            "initial_state, visibility, created_at, updated_at) VALUES "
            "(?,?, 'document', ?, 'super-draft','public', datetime('now'), datetime('now'))",
            (cid, pid, sub))


def test_content_repo_for_collection_resolves_per_project():
    _db()
    _seed()
    # Default project's collections → the default content repo.
    assert projects_mod.content_repo_for_collection("default") == "meta"
    assert projects_mod.content_repo_for_collection("features") == "meta"
    # The second project's collections → its own content repo.
    assert projects_mod.content_repo_for_collection("rfc-app") == "rfc-app-content"
    assert projects_mod.content_repo_for_collection("specs") == "rfc-app-content"


def test_content_repo_for_collection_unknown_is_none():
    _db()
    _seed()
    assert projects_mod.content_repo_for_collection("nope") is None


def test_entry_location_default_collection_repo_root():
    cfg = _db()
    _seed()
    org, repo, path = projects_mod.entry_location(cfg, "default", "alpha")
    assert (org, repo, path) == ("wiggleverse", "meta", "rfcs/alpha.md")


def test_entry_location_named_collection_uses_subfolder():
    cfg = _db()
    _seed()
    org, repo, path = projects_mod.entry_location(cfg, "features", "beta")
    assert (org, repo, path) == ("wiggleverse", "meta", "features/rfcs/beta.md")


def test_entry_location_other_project_distinct_repo():
    cfg = _db()
    _seed()
    # Named collection in a non-default project: distinct repo AND subfolder.
    org, repo, path = projects_mod.entry_location(cfg, "specs", "gamma")
    assert (org, repo, path) == ("wiggleverse", "rfc-app-content", "specs/rfcs/gamma.md")
    # Default collection of the non-default project: distinct repo, repo root.
    org, repo, path = projects_mod.entry_location(cfg, "rfc-app", "delta")
    assert (org, repo, path) == ("wiggleverse", "rfc-app-content", "rfcs/delta.md")


def test_entry_location_unknown_collection_falls_back_to_default_repo():
    cfg = _db()
    _seed()
    # An entry whose collection_id is missing/unknown must still resolve to a
    # usable location (the deployment default repo, repo root) rather than an
    # empty repo — the legacy single-corpus behaviour.
    org, repo, path = projects_mod.entry_location(cfg, "nope", "epsilon")
    assert (org, repo, path) == ("wiggleverse", "meta", "rfcs/epsilon.md")
