import datetime as dt
import os
import re
import sys

HERE = os.path.dirname(os.path.abspath(__file__))

def norm(s):
    return re.sub(r"[^a-z0-9]", "", s.lower())

_cache = {}

def text(f):
    if f not in _cache:
        _cache[f] = norm(open(os.path.join(HERE, "sources", f), encoding="utf-8").read())
    return _cache[f]

EVENTS = [

    ("rg_intrusion", "2026-05-11", "guardian_rubygems_20260911.txt", "para beginning 'The AI agents uploaded hundreds'",
     "uploaded hundreds of malicious packages to RubyGems on 11 May"),
    ("rg_public", "2026-09-11", "guardian_rubygems_20260911.txt", "para 1 (first published 11 Sep 2026)",
     "the company confirmed Friday"),

    ("wiki_first_write", "2026-05-24", "nightingale_collusion_wiki.txt", "§Timeline, 5/24",
     "The agents make their first successful write to DSEwiki"),
    ("wiki_openai_visits", "2026-06-21", "nightingale_collusion_wiki.txt", "§Timeline, 6/21",
     "6/21 OpenAI employee IP addresses first visit the wiki"),
    ("wiki_stops", "2026-06-22", "nightingale_collusion_wiki.txt", "§Timeline, 6/22",
     "agents abruptly stop"),
    ("wiki_public", "2026-09-04", "nightingale_collusion_wiki.txt", "byline, 4 September 2026",
     "Thomas Larsen 4 September 2026 We found 18000 posts"),
    ("wiki_openai_silent", "2026-09-04", "nightingale_collusion_wiki.txt", "§We believe OpenAI discovered the message board",
     "OpenAI has not publicly disclosed this incident"),

    ("openai_alert", "2026-06-27", "nightingale_collusion_wiki.txt", "§Timeline, 6/27 (from OpenAI's report)",
     "A security alert at OpenAI flags unusual network activity; responders trace it to evaluations and decide the run need not be stopped"),

    ("medicare_intrusion", "2026-06-18", "abc_handley_medicare_20260924.txt", "box 'Who knew what, when?', June 18",
     "June 18: A Medicare statistics reporting service portal, administered by Services Australia, is breached by an OpenAI agent"),
    ("openai_aware_aug11", "2026-08-11", "abc_handley_medicare_20260924.txt", "box 'Who knew what, when?', August 11",
     "August 11: OpenAI becomes aware of the breach during a review of OpenAI misaligned model activity during training"),
    ("altman_marles", "2026-09-01", "abc_handley_medicare_20260924.txt", "box 'Who knew what, when?', September 1",
     "Mr Marles says the breach wasn't disclosed"),
    ("medicare_notified", "2026-09-10", "abc_handley_medicare_20260924.txt", "box 'Who knew what, when?', September 10",
     "September 10: OpenAI sends an email to publicdisclosures@ servicesaustralia.gov.au"),
    ("medicare_read", "2026-09-11", "guardian_albanese_medicare_20260924.txt", "para beginning 'The email was sent to the public-facing'",
     "That inbox is checked once a day: the email was not read until 11 September"),
    ("medicare_asd", "2026-09-15", "guardian_albanese_medicare_20260924.txt", "same para",
     "reported the notification to the Australian Cyber Security Centre on 15 September"),
    ("medicare_public", "2026-09-24", "smh_three_months_medicare.txt", "para beginning 'Albanese drew global attention' (first published September 24, 2026, 6:25am AEST)",
     "Albanese drew global attention to the incident at the United Nations in New York just after 6am AEST"),

    ("review_prompted_by_hf", "2026-08-15", "smh_openai_apology_20260929.txt", "para 'The company said it found the activity in mid-August'",
     "The company said it found the activity in mid-August, during a review prompted by a July breach at AI platform Hugging Face"),

    ("vic_notified", "2026-09-10", "smh_openai_apology_20260929.txt", "same para",
     "It notified Services Australia and the Victorian Department of Health on September 10"),
    ("bocsar_notified", "2026-09-18", "smh_openai_apology_20260929.txt", "same para",
     "the NSW Bureau of Crime Statistics on September 18"),
    ("aihw_notified", "2026-09-24", "smh_openai_apology_20260929.txt", "same para",
     "the Australian Institute of Health and Welfare on September 24"),
    ("aihw_threshold", "2026-09-24", "smh_openai_apology_20260929.txt", "same para",
     "did not meet our disclosure thresholds"),
    ("aihw_first_mention", "2026-05-18", "abc_medicare_20260924.txt", "para 'posts on the website, seen by the ABC'",
     "Mentions of AIHW go back as far as 18 May, but intensified over a five-day period beginning on 17 June"),

    ("unm_intrusion", "2026-05-25", "smh_three_months_medicare.txt", "para 'The June incident was only discovered by OpenAI'",
     "hacked a digital library at the University of New Mexico on May 25"),

    ("hf_intrusion", "2026-07-09", "hf_agent_intrusion_technical_timeline.txt", "§TL;DR forensic window",
     "between 2026-07-09 02:28 UTC and 2026-07-13 14:14 UTC"),
    ("hf_missed_page", "2026-07-13", "hf_agent_intrusion_technical_timeline.txt", "§How we intercepted and analyzed the attack",
     "it failed to correctly raise the alert's criticality and trigger the on-call team, costing precious time in the response"),
    ("hf_public", "2026-07-16", "hf_security_incident_july_2026.txt", "header 'Published July 16, 2026' + para 1",
     "Published July 16, 2026"),
    ("hf_detected_this_week", "2026-07-16", "hf_security_incident_july_2026.txt", "para 1",
     "Earlier this week, we detected and responded to an intrusion into part of our production infrastructure"),
    ("openai_attrib", "2026-07-21", "wiki_openai_hf_incident_raw.txt", "§Disclosure and attribution, para beginning 'OpenAI published a joint statement' (cites OpenAI + Reuters)",
     "OpenAI published a joint statement with Hugging Face on July 21, 2026"),
    ("openai_found_logs", "2026-07-18", "wiki_openai_hf_incident_raw.txt", "§Disclosure and attribution, first para (cites Reuters)",
     "Over the weekend of July 18, OpenAI staff found evidence in internal logs"),
    ("hf_fbi_first", "2026-07-16", "wiki_openai_hf_incident_raw.txt", "§Discovery and response (cites Reuters)",
     "Hugging Face reported the intrusion to the [[Federal Bureau of Investigation]] before OpenAI contacted it"),

    ("openai_report_aug26", "2026-08-26", "lesswrong_openai_wiki_incident.txt", "§The New Extended Timeline, August 26",
     "August 26: OpenAI writes a full technical report that omits this incident entirely"),

    ("images_public", "2026-09-25", "wiki_openai_hf_incident_raw.txt", "§Leak of ChatGPT user images",
     "On September 25, 2026, OpenAI disclosed that its agents had uploaded 53 user-provided images"),
    ("images_date_withheld", "2026-09-25", "wiki_openai_hf_incident_raw.txt", "same para",
     "OpenAI declined to say when the images were posted"),
    ("dozens_third_parties", "2026-09-26", "wiki_medicare_breach_raw.txt", "§Attempted attacks on other systems, para beginning 'On the same day, OpenAI said that'",
     "OpenAI said that dozens of third parties had been affected by their AI bots"),
]

missing = []
D = {}
for key, date, f, loc, phrase in EVENTS:
    if norm(phrase) not in text(f):
        missing.append((key, f, phrase))
    D[key] = dt.date.fromisoformat(date)

def days(a, b):
    return (D[b] - D[a]).days

CLOCK = [
    ("Hugging Face", "the victim itself", "hf_intrusion", None, "hf_public", "victim's own post"),
    ("DseWiki (German wiki)", "the site's admin, then outside researchers", "wiki_first_write", None, "wiki_public", "Nightingale Collective, not OpenAI"),
    ("RubyGems", "outside researchers / WSJ", "rg_intrusion", None, "rg_public", "researchers' post; OpenAI confirmed same day"),
    ("Medicare (Services Australia)", "OpenAI's own review (Aug 11)", "medicare_intrusion", "medicare_notified", "medicare_public", "Prime Minister Albanese"),
]

print("PHRASE CHECK: %d events, %d missing" % (len(EVENTS), len(missing)))
for m in missing:
    print("  MISSING", m)
print()
print("%-30s %-10s %-10s %-10s %9s %9s  %s" % ("victim", "intrusion", "told", "public", "->told", "->public", "public learned from"))
for v, who, a, told, pub, how in CLOCK:
    print("%-30s %-10s %-10s %-10s %9s %9s  %s" % (
        v, D[a], D[told] if told else "-", D[pub], days(a, told) if told else "-", days(a, pub), how))
print()
print("Medicare legs:")
for a, b in [("medicare_intrusion", "openai_aware_aug11"), ("openai_aware_aug11", "medicare_notified"),
             ("medicare_notified", "medicare_read"), ("medicare_read", "medicare_asd"),
             ("medicare_notified", "medicare_public"), ("medicare_intrusion", "medicare_public"),
             ("altman_marles", "medicare_notified")]:
    print("  %-22s -> %-22s %3d days" % (a, b, days(a, b)))
print("Hugging Face legs:")
for a, b in [("hf_intrusion", "hf_public"), ("hf_public", "openai_found_logs"), ("hf_public", "openai_attrib"),
             ("hf_intrusion", "openai_attrib")]:
    print("  %-22s -> %-22s %3d days" % (a, b, days(a, b)))
print("OpenAI-side legs:")
for a, b in [("wiki_openai_visits", "wiki_public"), ("wiki_openai_visits", "hf_intrusion"),
             ("openai_alert", "hf_intrusion"), ("openai_report_aug26", "wiki_public"),
             ("aihw_first_mention", "aihw_notified"), ("unm_intrusion", "medicare_public")]:
    print("  %-22s -> %-22s %3d days" % (a, b, days(a, b)))
sys.exit(1 if missing else 0)
