"""Build v3 of the BoU Sandbox Application by applying targeted edits to the
operator's (final) docx. Preserves operator's manual edits (address,
2.6.4 tightening, 2.9 patent escalation, 2.8 founder bio) and applies:

 1. Legal entity: propagate Uganda-incorporated as primary frame (Q1)
 2. Patent: keep "filed" framing, replace XXXXXX with impossible-to-miss marker (Q2)
 3. National AI Strategy: soften §2.1 to "draft" to match §2.8 (Q4)
 4. §5.5 retail-investor sentence restored with operator's framing (Q5)
 5. B4: de facto CRO → formal pending-appointment language
 6. B5: IR retainer → honest pre-screened panel reframe (Q3 default)
 7. C2: Ghost Core bridging sentence in §3.3
 8. C3: Schedule 2 "Enclosed" → "ENCLOSED"
 9. House style: "Aegis Cyber" in §2.9 → "AEGIS CYBER"
10. §1.1 grammar: "require" → "requires"
11. Appendix double-space fix
12. §2.1 "production ready" → "production-ready"
"""
from docx import Document
from pathlib import Path

SRC = "attached_assets/SANDBOX_APPLICATION_AEGIS_CYBER_BoU_Sandbox_Application_(fina_1779125205511.docx"
DST = "attached_assets/AEGIS_CYBER_BoU_SANDBOX_APPLICATION_v3_2026-05-18.docx"

# (find_substring, full_old_text, full_new_text)
# find_substring is just used to locate the paragraph; replacement is whole-text.
EDITS = [
    # 1. §2.1 — flip legal entity to Uganda-primary + soften National AI Strategy + production-ready hyphen
    (
        "AEGIS SOVEREIGN Limited is a technology company incorporated in the United Kingdom",
        "AEGIS SOVEREIGN Limited is a technology company incorporated in the United Kingdom (Companies House Registration No. 16991209), with a Uganda subsidiary registration in progress with URSB, and operations across Uganda and the United Kingdom. AEGIS CYBER is its cybersecurity and compliance intelligence platform, purpose-built as a multi-tenant SaaS solution for the East African financial sector.",
        "AEGIS SOVEREIGN Limited is a technology company incorporated in Uganda (URSB Registration No. 80034378165810), with a UK affiliate (Companies House No. 16991209) supporting UK and international operations. AEGIS CYBER is its cybersecurity and compliance intelligence platform, purpose-built as a multi-tenant SaaS solution for the East African financial sector.",
    ),
    (
        "The platform is production ready.",
        "The platform is production ready. The most recent internal security audit (AUDIT-CYBER-2026-05-15) identified zero High-severity findings; four Medium-severity items are tracked in the AEGIS Legacy Carve-Outs Register v1.1 with documented justifications and target close dates.",
        "The platform is production-ready. The most recent internal security audit (AUDIT-CYBER-2026-05-15) identified zero High-severity findings; four Medium-severity items are tracked in the AEGIS Legacy Carve-Outs Register v1.1 with documented justifications and target close dates.",
    ),
    (
        "authored Uganda's National AI Strategy (2026",
        "The founder, Moses Mwesigwa, authored Uganda's National AI Strategy (2026\u20132035) \u2014 a presidential-level, Vision 2040-aligned policy document \u2014 and represented Uganda's innovation agenda at the World Economic Forum in Davos in January 2026. The company seeks approval to operate within the BoU Regulatory Sandbox to validate the platform's payment security capabilities and obtain the operational evidence required to support full licensing and institutional rollout.",
        "The founder, Moses Mwesigwa, authored the draft of Uganda's National AI Strategy (2026\u20132035) \u2014 a presidential-level, Vision 2040-aligned policy document currently under government review \u2014 and represented Uganda's innovation agenda at the World Economic Forum in Davos in January 2026. The company seeks approval to operate within the BoU Regulatory Sandbox to validate the platform's payment security capabilities and obtain the operational evidence required to support full licensing and institutional rollout.",
    ),
    # 2. §2.8 — drop "Uganda subsidiary registration in progress" (it is complete per Q1); tidy founder bio Strategy wording
    (
        "Modern Workplace Engineer for Newham Council (London) and author of draft Uganda's National AI Strategy",
        "AEGIS CYBER is founder-led by Moses Mwesigwa, who combines public policy expertise \u2014 due to his recent role as Modern Workplace Engineer for Newham Council (London) and author of draft Uganda's National AI Strategy \u2014 with deep technical capability as the lead architect of the platform. The founder has relocated from London to Kampala and maintains dual operational presence in both jurisdictions.",
        "AEGIS CYBER is founder-led by Moses Mwesigwa, who combines public policy expertise \u2014 most recently as Modern Workplace Engineer for Newham Council (London) and as author of the draft of Uganda's National AI Strategy (currently under government review) \u2014 with deep technical capability as the lead architect of the platform. The founder has relocated from London to Kampala and maintains dual operational presence in both jurisdictions.",
    ),
    (
        "AEGIS SOVEREIGN's Uganda subsidiary registration is in progress with the Uganda Registration Services Bureau.",
        "AEGIS SOVEREIGN's Uganda subsidiary registration is in progress with the Uganda Registration Services Bureau. The company holds a Technology Innovation Centre membership and has active engagement with the Uganda Communications Commission on matters of cybersecurity standards and digital infrastructure resilience.",
        "AEGIS SOVEREIGN is incorporated in Uganda (URSB Registration No. 80034378165810) with a UK affiliate (Companies House No. 16991209). The company holds a Technology Innovation Centre membership and has active engagement with the Uganda Communications Commission on matters of cybersecurity standards and digital infrastructure resilience.",
    ),
    # 3. §2.9 — house-style fix + replace XXXXXX with impossible-to-miss marker
    (
        "Aegis Cyber patent application filed with the UK IPO",
        "Aegis Cyber patent application filed with the UK IPO (application number XXXXXX, pending examination), covering the ML-KEM-768 mesh integration architecture, Hybrid Logical Clock transaction ordering, and the Sovereign Failover protocol. This protects the core innovations of the platform as exclusive intellectual property of AEGIS SOVEREIGN Limited.",
        "AEGIS CYBER patent application filed with the UK IPO (application number [INSERT GB APPLICATION NUMBER BEFORE SUBMISSION], pending examination), covering the ML-KEM-768 mesh integration architecture, Hybrid Logical Clock transaction ordering, and the Sovereign Failover protocol. This protects the core innovations of the platform as exclusive intellectual property of AEGIS SOVEREIGN Limited.",
    ),
    # 4. §3.3 — add Ghost Core bridging sentence (C2)
    (
        "Cross-border transaction analysis and the Ghost Core proxy mode (CBS failover) will be simulated in a dedicated test environment with synthetic data only.",
        "The sandbox scope is limited to: the Uganda jurisdiction; transactions denominated in UGX; and the specific modules identified in Section 3.1. Cross-border transaction analysis and the Ghost Core proxy mode (CBS failover) will be simulated in a dedicated test environment with synthetic data only.",
        "The sandbox scope is limited to: the Uganda jurisdiction; transactions denominated in UGX; and the specific modules identified in Section 3.1. Cross-border transaction analysis and the Ghost Core proxy mode (CBS failover) will be simulated in a dedicated test environment with synthetic data only. Ghost Core is deliberately held out of live sandbox scope because it touches payment execution paths, which the sandbox is designed to insulate from any platform issue during early validation. Live validation of Ghost Core is contemplated as a discrete subsequent sandbox phase, on terms to be agreed separately with the Bank of Uganda.",
    ),
    # 5. §4.3 — remove URSB-registration line (URSB is complete per Q1)
    (
        "registration of the company with URSB",
        "The primary intended exit from the sandbox is successful completion, leading to an application for a full commercial operating licence under the National Payment Systems Act 2020. Parallel to the sandbox, AEGIS SOVEREIGN will pursue: registration of the company with URSB; application to the UCC Technology Innovation Fund; and engagement with the BoU FinTech Regulatory Sandbox Programme for any payment-adjacent modules that require specific payment system licensing.",
        "The primary intended exit from the sandbox is successful completion, leading to an application for a full commercial operating licence under the National Payment Systems Act 2020. Parallel to the sandbox, AEGIS SOVEREIGN will pursue: application to the UCC Technology Innovation Fund; and engagement with the BoU FinTech Regulatory Sandbox Programme for any payment-adjacent modules that require specific payment system licensing.",
    ),
    # 6. §5.1 — B4 de facto CRO → formal pending-appointment
    (
        "who serves as de facto Chief Risk Officer during the sandbox phase",
        "AEGIS SOVEREIGN's risk management framework is owned by the Founder and Director, Moses Mwesigwa, who serves as de facto Chief Risk Officer during the sandbox phase. A formal risk register is maintained and reviewed monthly. All risks are classified using a 5\u00d75 likelihood-impact matrix. Risks rated High or Critical trigger an immediate escalation protocol and are reported to the Bank of Uganda within 48 hours of identification.",
        "AEGIS SOVEREIGN's risk management framework is owned by the Founder and Director, Moses Mwesigwa, who holds the Chief Risk Officer function during the sandbox phase, pending appointment of a dedicated CRO at Series A close. A formal risk register is maintained and reviewed monthly. All risks are classified using a 5\u00d75 likelihood-impact matrix. Risks rated High or Critical trigger an immediate escalation protocol and are reported to the Bank of Uganda within 48 hours of identification.",
    ),
    # 7. §5.5 — restore retail-investor sentence per Q5
    (
        "with full access to financial projections and risk disclosures.",
        "AEGIS SOVEREIGN does not accept deposits, manage client funds, or operate as a financial intermediary. No retail investors or members of the public have any financial exposure to the platform. The only investors are AEGIS SOVEREIGN's equity holders, who have made informed investment decisions with full access to financial projections and risk disclosures. ",
        "AEGIS SOVEREIGN does not accept deposits, manage client funds, or operate as a financial intermediary. No retail investors or members of the public have any financial exposure to the platform. The only investors are AEGIS SOVEREIGN's equity holders, who have made informed investment decisions with full access to financial projections and risk disclosures. AEGIS SOVEREIGN has taken no retail investment or public funding to date. During the sandbox period, no new equity will be raised from retail investors or members of the public.",
    ),
    # 8. §5.6 — B5 IR retainer honest reframe (Q3 default)
    (
        "engagement of the pre-identified incident response retainer",
        "In the event of a security incident during the sandbox period, the following response protocol applies. Upon detection: immediate isolation of affected systems; notification to the Bank of Uganda and the pilot institution within 4 hours; engagement of the pre-identified incident response retainer. Within 24 hours: root cause analysis; assessment of scope and impact; notification to NITA-U if personal data is involved. Within 72 hours: full incident report submitted to the Bank of Uganda; remediation actions implemented; communications to affected parties. Post-incident: independent security review; updated security audit; lessons-learned report shared with BoU.",
        "In the event of a security incident during the sandbox period, the following response protocol applies. Upon detection: immediate isolation of affected systems; notification to the Bank of Uganda and the pilot institution within 4 hours; engagement of an external incident response provider from the pre-screened panel maintained by AEGIS SOVEREIGN. Within 24 hours: root cause analysis; assessment of scope and impact; notification to NITA-U if personal data is involved. Within 72 hours: full incident report submitted to the Bank of Uganda; remediation actions implemented; communications to affected parties. Post-incident: independent security review; updated security audit; lessons-learned report shared with BoU.",
    ),
    # 9. §1.1 — grammar regression
    (
        "The Data Protection and Privacy Act 2019 require verifiable audit trails",
        "The Data Protection and Privacy Act 2019 require verifiable audit trails",
        "The Data Protection and Privacy Act 2019 requires verifiable audit trails",
    ),
]

# Appendix table-cell fixes (separate because they live in table cells, not paragraphs)
CELL_EDITS = [
    ("ENCLOSED ( Uganda Certificate of Incorporation with URSB)",
     "ENCLOSED (Uganda Certificate of Incorporation with URSB)"),
    ("Enclosed (Moses Mwesigwa \u2014 Founder)",
     "ENCLOSED (Moses Mwesigwa \u2014 Founder)"),
]


def replace_paragraph_text(para, new_text):
    """Replace paragraph text while preserving paragraph style.
    Collapses runs into a single run (acceptable for body text)."""
    # Get first run's font properties to preserve them
    if para.runs:
        first_run = para.runs[0]
        # Clear all runs
        for run in para.runs[1:]:
            run.text = ""
        first_run.text = new_text
    else:
        para.add_run(new_text)


def apply_edits():
    d = Document(SRC)
    applied = []
    missed = []

    # Apply paragraph edits (also covers table-cell paragraphs)
    def iter_all_paragraphs(doc):
        for p in doc.paragraphs:
            yield p
        for t in doc.tables:
            for row in t.rows:
                for cell in row.cells:
                    for p in cell.paragraphs:
                        yield p

    paragraphs = list(iter_all_paragraphs(d))

    for find_sub, old_text, new_text in EDITS:
        found = False
        for p in paragraphs:
            if find_sub in p.text and p.text.strip() == old_text.strip():
                replace_paragraph_text(p, new_text)
                applied.append(find_sub[:60])
                found = True
                break
        if not found:
            # Fallback: try fuzzy match (paragraph contains find_sub but text differs)
            for p in paragraphs:
                if find_sub in p.text:
                    # Do an in-place substring replacement
                    if old_text.strip() in p.text:
                        new_p_text = p.text.replace(old_text.strip(), new_text)
                        replace_paragraph_text(p, new_p_text)
                        applied.append(find_sub[:60] + " (fuzzy)")
                        found = True
                        break
        if not found:
            missed.append(find_sub[:80])

    # Apply table-cell edits (for cells whose entire text matches)
    for old_cell, new_cell in CELL_EDITS:
        found = False
        for t in d.tables:
            for row in t.rows:
                for cell in row.cells:
                    if cell.text.strip() == old_cell.strip():
                        # Rewrite all paragraphs in cell
                        for i, p in enumerate(cell.paragraphs):
                            if i == 0:
                                replace_paragraph_text(p, new_cell)
                            else:
                                replace_paragraph_text(p, "")
                        applied.append(f"CELL: {old_cell[:60]}")
                        found = True
                        break
                if found:
                    break
            if found:
                break
        if not found:
            missed.append(f"CELL: {old_cell[:80]}")

    d.save(DST)
    return applied, missed


if __name__ == "__main__":
    applied, missed = apply_edits()
    print(f"Applied: {len(applied)}")
    for a in applied:
        print(f"  OK  {a}")
    print(f"Missed: {len(missed)}")
    for m in missed:
        print(f"  MISS {m}")
    print(f"\nOutput: {DST}")
    print(f"Size: {Path(DST).stat().st_size} bytes")
