"""One-time migration: legacy frozensets → concept_relations rows.

Pre-2026-05-01 the synonym & rivalry data lived as hand-curated frozensets
in ``aborist.qa.concepts``. This module preserves those tuples & writes
them as ``evidence_kind='manual_legacy'`` rows so the DB-backed lookup
returns the same answers the frozenset lookup did.

Idempotent: re-running ``seed_legacy_concepts`` is safe because the
INSERT OR IGNORE in ``add_concept_relation`` falls through on duplicates.

The legacy data writes to a designated ``source_root`` value
(``__legacy__concepts__``) since these relations were not derived from
any specific document. New extractors writing relations from a real
document use the document's actual ``document_root``.
"""

from __future__ import annotations

import sqlite3

from aborist.concepts.store import add_concept_relation

# Sentinel source_root for legacy seed data. Real concept relations
# from corpus extractors use the document's actual document_root so
# the per-source-root provenance stays intact.
LEGACY_SOURCE_ROOT = "__legacy__concepts__"
LEGACY_EVIDENCE_KIND = "manual_legacy"


# Snapshot of the frozenset groups as of commit bde1bd6 (2026-05-01).
# Each group becomes a fully-connected synonym cluster: every pair of
# tokens within the group becomes a synonym edge. Union-find at lookup
# time collapses these back into the same equivalence class.
LEGACY_SYNONYM_GROUPS: list[tuple[str, ...]] = [
    # AMD CPU family
    ("amd", "athlon", "duron", "opteron", "ryzen", "epyc",
     "thunderbird", "palomino", "thoroughbred", "barton",
     "k6", "k7", "k8", "k10", "5x86"),
    # Intel CPU family
    ("intel", "pentium", "celeron", "xeon", "itanium",
     "i7", "i5", "i3", "i9",
     "core2", "coreduo", "skylake", "haswell", "ivy",
     "8086", "80286", "80386", "80486"),
    # HTTP / web protocol family
    ("http", "https", "hypertext", "rfc2068", "rfc2616"),
    # FTP / file-transfer family
    ("ftp", "sftp", "ftps"),
    # Mac family
    ("macintosh", "mac", "macos", "osx", "apple"),
    # Windows family
    ("windows", "microsoft", "win32", "winnt", "win9x"),
    # Linux family
    ("linux", "gnu", "ubuntu", "debian", "fedora", "redhat", "kernel"),
    # Mind-reading / brain-computer-interface family (added 2026-05-01)
    ("telepathy", "telepathic", "neurotechnology", "neuroscience",
     "neuroimaging", "neural", "neuron", "neurons",
     "brain", "brains", "mind", "minds", "cognition", "cognitive",
     "consciousness", "thoughts", "thinking", "thought",
     "psychic", "psychokinesis", "esp", "clairvoyance",
     "fmri", "eeg", "fnirs", "meg", "ecog",
     "tms", "transcranial", "bci"),
]

# Legacy rivalry pairs: a single edge between any token in group A and
# any token in group B captures the rivalry; lookup-time closure
# expands it to the whole synonym cluster on each side. We pick the
# canonical first token of each group as the representative.
LEGACY_RIVALRY_REPRESENTATIVES: list[tuple[str, str]] = [
    ("amd", "intel"),    # AMD ↔ Intel
    ("apple", "windows"),  # Mac ↔ Windows  (group reps)
]


def seed_legacy_concepts(conn: sqlite3.Connection) -> dict:
    """Seed the legacy frozensets into ``concept_relations`` on ``conn``.

    Returns ``{"synonyms_inserted": N, "rivalries_inserted": M,
    "synonyms_skipped": K, "rivalries_skipped": L}``. Skipped counts
    indicate rows that already existed (idempotent re-seed).
    """
    syn_ins = syn_skip = riv_ins = riv_skip = 0

    # Synonyms: emit a clique edge for every (a, b) pair within each
    # group. Lookup is direct-neighbor (no transitive closure across
    # groups) so we need the full N*(N-1)/2 pairs to preserve the
    # legacy frozenset semantic where every member retrieved every
    # other member. Quadratic in group size but groups stay small
    # (largest is the 30-member brain-tech set → 435 pairs).
    for group in LEGACY_SYNONYM_GROUPS:
        if len(group) < 2:
            continue
        members = list(group)
        for i, a in enumerate(members):
            for b in members[i + 1:]:
                inserted = add_concept_relation(
                    conn,
                    source_root=LEGACY_SOURCE_ROOT,
                    relation_kind="synonym",
                    token=a,
                    target=b,
                    evidence_kind=LEGACY_EVIDENCE_KIND,
                    derived_from="aborist.qa.concepts (legacy frozensets)",
                )
                if inserted:
                    syn_ins += 1
                else:
                    syn_skip += 1

    # Rivalries: one row per representative pair. Group closure happens
    # at lookup time via the synonym index.
    for a, b in LEGACY_RIVALRY_REPRESENTATIVES:
        inserted = add_concept_relation(
            conn,
            source_root=LEGACY_SOURCE_ROOT,
            relation_kind="rivalry",
            token=a,
            target=b,
            evidence_kind=LEGACY_EVIDENCE_KIND,
            derived_from="aborist.qa.concepts (legacy frozensets)",
        )
        if inserted:
            riv_ins += 1
        else:
            riv_skip += 1

    conn.commit()
    return {
        "synonyms_inserted": syn_ins,
        "rivalries_inserted": riv_ins,
        "synonyms_skipped": syn_skip,
        "rivalries_skipped": riv_skip,
    }
