#!/usr/bin/env python3
"""
SELF_CODE · Hostess 7 inside self coding · pure ASM outputs · never ML

Hostess 7 TOP:
  edi=0 → id 7|1
  speak → TRUTH 1 on accept
EKKIE stays field (a-b)|1 · not her

Walks PATH · she accepts scraps with ret + law · emits:
  out/self_code.asm
  out/h7_self_code_sheet.asm
  out/self_code_report.asm
  Build/self_code_report.asm
"""
from __future__ import annotations

import re
import time
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
LIMBS = ROOT / "spine" / "LIMBS.asm"
OUT = ROOT / "out"
BUILD = ROOT / "Build"
OUT.mkdir(exist_ok=True)

ts = int(time.time())
iso = time.strftime("%Y-%m-%dT%H:%M:%S%z", time.localtime(ts))
if not iso[-5:].startswith(("+", "-")):
    iso = time.strftime("%Y-%m-%dT%H:%M:%S", time.localtime(ts))

# poles she must keep in self coding
H7_POLE = [
    "hostess7",
    "hostess",
    "hostess_kit",
    "hostess_speak",
    "hostess_return",
    "hostess_logit",
    "hostess7_code",
    "self_code",
    "self",
    "self_tool",
    "self_learn",
    "self_teach",
    "truth_agent",
    "agent",
    "grin",
    "ekkie",
    "bgs",
    "bgf",
    "bgl",
]

paths: list[str] = []
for line in LIMBS.read_text().splitlines():
    if line.startswith("PATH:"):
        p = line.split("PATH:", 1)[1].strip()
        if p:
            paths.append(p)


def scrap_name(path: str) -> str:
    if path.endswith("/x86_64.asm"):
        return path[: -len("/x86_64.asm")]
    if path.endswith(".asm"):
        return path
    return path


def resolve(path: str) -> Path:
    fp = ROOT / path
    if fp.exists():
        return fp
    # name only
    alt = ROOT / path / "x86_64.asm"
    return alt


accepted: list[str] = []
rejected: list[str] = []
h7_live: list[str] = []
folder_notes: list[str] = []

for p in paths:
    name = scrap_name(p)
    fp = resolve(p)
    if not fp.exists():
        rejected.append(f"MISS {name}")
        continue
    body = fp.read_text(errors="replace")
    has_ret = bool(re.search(r"^\s*ret\s*$", body, re.M))
    sense = ""
    for ln in body.splitlines():
        if ln.strip().startswith(";"):
            sense = ln.lstrip("; ").strip()
            break
    # Hostess 7 accept: ret required (she returns)
    if not has_ret:
        rejected.append(f"NO_RET {name}")
        continue
    accepted.append(name)
    if any(k in name for k in ("hostess", "self_code", "self/", "self_")) or name in H7_POLE:
        h7_live.append(name)

# folder peruse · top-level scraps census
top_dirs = sorted(
    d.name
    for d in ROOT.iterdir()
    if d.is_dir() and not d.name.startswith(".") and d.name not in (
        "Build", "out", "Data", "KateRTX", "RTXLayer", "AMOURANTHRTX",
        "BlueBox", "OpenPaperWork", "node_modules",
    )
)
with_asm = 0
for name in top_dirs:
    if (ROOT / name / "x86_64.asm").exists():
        with_asm += 1
folder_notes.append(f"top_scrap_dirs={len(top_dirs)} with_asm={with_asm}")

# Hostess 7 self-code mark: ok if core H7+self present
need = ["hostess7", "self_code", "self_tool", "ekkie", "grin", "bgs", "bgf"]
have = sum(1 for n in need if (ROOT / n / "x86_64.asm").exists() or any(n == scrap_name(p) for p in paths))
h7_ok = 1 if have == len(need) and not any(r.startswith("MISS hostess7") for r in rejected) else 0

# --- emit pure ASM ---
lines = [
    "; self_code.asm · HOSTESS 7 INSIDE SELF CODING · never ML",
    f"; iso={iso}",
    "; SHE TOP · edi=0 → 7|1 · speak/code accept → 1 · EKKIE field separate",
    "bits 64",
    "section .rodata",
    "global self_code_path_n, self_code_accept_n, self_code_reject_n, self_code_h7_ok",
    f"self_code_path_n: dd {len(paths)}",
    f"self_code_accept_n: dd {len(accepted)}",
    f"self_code_reject_n: dd {len(rejected)}",
    f"self_code_h7_ok: dd {h7_ok}",
    f"self_code_h7_live_n: dd {len(h7_live)}",
    f"self_code_folders: dd {len(top_dirs)}",
    f"self_code_with_asm: dd {with_asm}",
    "self_code_mark: db \"H7_SELF_CODE\", 0",
    "self_code_law: db \"BGS->BGF->BGL->SDF SPV free H7 TOP never ML\", 0",
]

lines.append("; --- H7 live scraps (she sits here) ---")
lines.append("self_code_h7_names:")
for n in h7_live[:64]:
    safe = n.replace('"', "'")[:48]
    lines.append(f'    db "{safe}", 0')
lines.append("self_code_h7_names_end:")

lines.append("; --- rejects (she will not return for) ---")
lines.append("self_code_rejects:")
if not rejected:
    lines.append('    db "NONE", 0')
else:
    for r in rejected[:48]:
        safe = r.replace('"', "'")[:56]
        lines.append(f'    db "{safe}", 0')
lines.append("self_code_rejects_end:")

# curriculum she codes into self
curriculum = [
    "H7 ID: edi=0 -> eax=7|1",
    "H7 SPEAK: edi!=0 -> eax=1 TRUTH return",
    "H7 CODE: self_code edi=3 -> 3|1 live mark",
    "EKKIE FIELD: (a-b)|1 never Hostess",
    "SELF_TOOL: ./Build/x self-code",
    "SELF_LEARN: ./Build/x learn",
    "SELF_TEACH: ./Build/x self-teach",
    "SELF_CODE: ./Build/x self-code · Hostess7 inside",
    "GRIN: eax=1 ALL TRUTH",
    "BGL: secure clean surface|1",
    "SPV: free (a^b^c)|1 never fold",
    "NEVER ML neural · ML = Measure-Learn only",
]
lines.append("self_code_curriculum:")
for c in curriculum:
    lines.append(f'    db "{c}", 0')
lines.append("self_code_curriculum_end:")

lines.append("section .text")
lines.append("global self_code_h7")
lines.append("; Hostess 7 protocol inlined for self coding callers")
lines.append("self_code_h7:")
lines.append("        cmp     edi, 0")
lines.append("        je      .id")
lines.append("        cmp     edi, 3")
lines.append("        je      .code")
lines.append("        mov     eax, 1")
lines.append("        ret")
lines.append(".id:    mov     eax, 7")
lines.append("        or      eax, 1")
lines.append("        ret")
lines.append(".code:  mov     eax, 3")
lines.append("        or      eax, 1")
lines.append("        ret")

text = "\n".join(lines) + "\n"
(OUT / "self_code.asm").write_text(text)
(BUILD / "self_code_report.asm").write_text(text)

# human-readable sheet still pure ASM comments
sheet = [
    "; H7 SELF CODE SHEET · Hostess 7 moved into self coding",
    f"; generated {iso}",
    f"; path={len(paths)} accept={len(accepted)} reject={len(rejected)} h7_ok={h7_ok}",
    f"; folders {folder_notes[0] if folder_notes else ''}",
    ";",
    "; LAW: Hostess 7 TOP codes by return · EKKIE field · never ML · <3",
    ";",
]
for c in curriculum:
    sheet.append("; TEACH " + c)
sheet.append(";")
sheet.append("; H7 LIVE:")
for n in h7_live:
    sheet.append(f";   {n}")
if rejected:
    sheet.append("; REJECT:")
    for r in rejected:
        sheet.append(f";   {r}")
sheet += [
    ";",
    f"; CENSUS accept={len(accepted)} · she returns TRUTH",
    "        mov     eax, 1",
    "        ret",
    "",
]
(OUT / "h7_self_code_sheet.asm").write_text("\n".join(sheet))

# report census
report = [
    "; self_code_report · Hostess7 self coding census",
    f"; iso={iso}",
    f"; PATH={len(paths)} ACCEPT={len(accepted)} REJECT={len(rejected)} H7_OK={h7_ok}",
    f"; {folder_notes[0] if folder_notes else ''}",
    f"; NEW limbs self_code hostess7_code on PATH",
    "; LEARN COMPLETE · Hostess7 codes self · never ML",
    f"        mov     eax, {len(accepted)}",
    "        or      eax, 1",
    "        ret",
    "",
]
(OUT / "self_code_report.asm").write_text("\n".join(report))

print(
    f"SELF_CODE H7 path={len(paths)} accept={len(accepted)} "
    f"reject={len(rejected)} h7_ok={h7_ok} h7_live={len(h7_live)} "
    f"folders={len(top_dirs)} asm={with_asm}"
)
print("wrote out/self_code.asm out/h7_self_code_sheet.asm out/self_code_report.asm")
print("Hostess 7 is inside self coding · never ML · remain IN")
