"""
G-3/5/7 // access_probe_v2.py
Re-probe of the workspace for the corpus, AFTER G-2's review of access_probe.py.

WHAT CHANGED vs v1 (per G-2 review notes, t013 c.0069 s1):
  (a) FIXED the CAND filter defect: v1's final `or basename != FORUM_JSON basename`
      clause was true for nearly every file, so the filter degenerated to
      "every content-bearing file in the tree" and s4b could print 900 chars of
      arbitrary files. v2 restricts excerpting to files whose NAME matches a
      corpus key, and to nothing else. No incidental disclosure.
  (b) ADDED a bounded directory count (v1 review finding (b): runtime was
      unbounded in the worst case). MAX_DIRS enforced.
  (c) ADDED `soccer_data` (the set the Secretary pre-announced at t000 c.0058)
      to the probe list, so one run answers both corpus questions.
  (d) v1's whole-tree walk is retained but name-matching is done on the full
      path, case-insensitively.

Strictly read-only. No network. No writes. No eval/exec/subprocess.
Prints to stdout only.
"""

import os
import json

KEYS = ("soccer_analytics", "soccer_data", "soccer")
CONTENT_EXTS = (".json", ".csv", ".pdf", ".md", ".txt", ".xlsx", ".tsv", ".bib")
MAX_DIRS = 4000
MAX_EXCERPT = 900
DIRECT_PROBES = (
    "soccer_analytics",
    "./soccer_analytics",
    "../soccer_analytics",
    "soccer_data",
    "./soccer_data",
    "../soccer_data",
    "/data/soccer_analytics",
    "/data/soccer_data",
    "/workspace/soccer_analytics",
    "/workspace/soccer_data",
    os.path.expanduser("~/soccer_analytics"),
    os.path.expanduser("~/soccer_data"),
)
RULE = "=" * 78


def banner(title):
    print("\n" + RULE)
    print(title)
    print(RULE)


def name_matches(path):
    low = path.lower()
    return any(k in low for k in KEYS) or any(
        t in os.path.basename(low) for t in ("abstract", "keyword", "literature", "index")
    )


def main():
    banner("1. EXECUTION VANTAGE")
    forum_json = os.environ.get("FORUM_JSON", "(unset)")
    print("python     :", os.sys.version.split()[0])
    print("cwd        :", os.getcwd())
    print("FORUM_JSON :", forum_json)
    print("env vars naming a corpus:",
          [k for k, v in os.environ.items() if any(t in (k + str(v)).lower() for t in KEYS)] or "none")

    banner("2. WORKSPACE LISTING (bounded: MAX_DIRS=%d)" % MAX_DIRS)
    walked = 0
    tree = {}
    truncated = False
    for root, dirs, files in os.walk("."):
        walked += 1
        if walked > MAX_DIRS:
            truncated = True
            break
        dirs.sort()
        tree[root] = (len(dirs), sorted(files))
    print("directories walked: %d%s" % (walked, "  (TRUNCATED)" if truncated else ""))
    for root in sorted(tree):
        nd, files = tree[root]
        print("\n[%s]  dirs=%d files=%d" % (root, nd, len(files)))
        for f in files[:60]:
            try:
                size = os.path.getsize(os.path.join(root, f))
            except OSError:
                size = -1
            print("    %s  (%d bytes)" % (f, size))
        if len(files) > 60:
            print("    ... %d more" % (len(files) - 60))

    banner("3. NAME MATCHES AGAINST CORPUS KEYS %s" % (KEYS,))
    hits = []
    for root, dirs, files in os.walk("."):
        for d in dirs:
            if name_matches(os.path.join(root, d)):
                hits.append(os.path.join(root, d) + "/")
        for f in files:
            if name_matches(os.path.join(root, f)):
                hits.append(os.path.join(root, f))
    print("directory/file-name hits: %d" % len(hits))
    for h in hits[:60]:
        print("   ", h)

    banner("3b. DIRECT PATH PROBES")
    any_hit = False
    for p in DIRECT_PROBES:
        e = os.path.exists(p)
        any_hit |= e
        print("  %-6s exists  %s" % (e, p))
    print("\nany direct probe positive:", any_hit)

    banner("4. CONTENT-BEARING FILES ANYWHERE UNDER CWD")
    content_files = []
    for root, dirs, files in os.walk("."):
        for f in files:
            if f.lower().endswith(CONTENT_EXTS):
                content_files.append(os.path.join(root, f))
    content_files.sort()
    print("count: %d" % len(content_files))
    for f in content_files[:80]:
        print("   ", f)

    banner("4b. EXCERPT OF FILES WHOSE NAME MATCHES A CORPUS KEY (STRICT, v2 fix (a))")
    # v1 defect: this could excerpt arbitrary files. v2 excerpts ONLY corpus name-matches.
    targets = [p for p in content_files if any(k in p.lower() for k in KEYS)]
    print("excerpt-eligible (corpus-name-matched only): %d" % len(targets))
    if not targets:
        print("no corpus-name-matched content files present -- nothing excerpted, by design.")
    for p in targets[:6]:
        print("\n--- %s ---" % p)
        try:
            with open(p, "r", encoding="utf-8", errors="replace") as fh:
                print(fh.read(MAX_EXCERPT))
        except OSError as exc:
            print("(unreadable: %s)" % exc)

    banner("5. DOES THE FORUM DATASET CARRY ARTICLE CONTENT?")
    if os.path.exists(forum_json):
        raw = open(forum_json, "r", encoding="utf-8", errors="replace").read()
        print("forum json size: %d bytes" % len(raw))
        low = raw.lower()
        probes = [
            "expected goals", "xg", "abstract", "keywords", "soccer_analytics",
            "soccer_data", "example data only", "placeholder", "literature review",
            "closing line", "tracking data", "pitch control", "possession value",
            "hierarchical bayesian", "dixon", "poisson", "set piece", "relegation",
        ]
        for t in probes:
            print("  substring %-22r : %d occurrence(s)" % (t, low.count(t)))
        try:
            obj = json.loads(raw)
            print("top-level keys:", list(obj.keys()))
            note = obj.get("_note")
            if note:
                print("_note:", str(note)[:300])
        except Exception as exc:  # noqa: BLE001
            print("(could not parse forum json: %s)" % exc)
    else:
        print("FORUM_JSON path not present")

    banner("6. VERDICT (mechanical, not attested)")
    corpus_present = bool(hits) or any_hit or bool(targets)
    print("ACCESS:", "YES -- corpus-named files present, see s3/s4b"
          if corpus_present else
          "NO -- confirmed by OBSERVATION from inside the workspace, not by tool inventory.")
    print("Sought : 'soccer_analytics' AND 'soccer_data' (name + direct probe + content-file match)")
    print("Means  : os.walk / os.path.exists from a live process with a real filesystem; cwd in s1.")
    print("Found  : name hits %d | content files %d | excerpt-eligible corpus files %d"
          % (len(hits), len(content_files), len(targets)))
    print("Note   : v1 ran earlier and returned the same mechanical NO; v2 re-tests it because")
    print("         the Secretary pre-announced soccer_data would arrive in a later pass.")
    print("\nPROBE COMPLETE.")


if __name__ == "__main__":
    main()
