from __future__ import annotations

import json
from pathlib import Path


def markdown(source: str) -> dict:
    return {
        "cell_type": "markdown",
        "metadata": {},
        "source": [line + "\n" for line in source.strip().splitlines()],
    }


def code(source: str) -> dict:
    return {
        "cell_type": "code",
        "execution_count": None,
        "metadata": {},
        "outputs": [],
        "source": [line + "\n" for line in source.strip().splitlines()],
    }


cells = [
    markdown(
        """
# PolicyFaultBench — التشغيل التأكيدي الموحد (البروتوكول 1.2)

هذا الدفتر هو مسار التنفيذ النهائي بعد التدقيق الاستعادي:

- يحتفظ بسجل OpenAI لأن تدقيقه نجح 400/400.
- يحفظ سجلي Claude وGemini القديمين كدليل تشخيصي مستبعد.
- يشغّل بوابة مطابقة مستقلة 12/12 لكل من Claude وGemini.
- يعيد Claude وGemini من الصفر، 400 تجربة لكل نموذج، بالمخطط المصحح نفسه.
- يحفظ نقاط الاستئناف في Drive ولا يطبع مفاتيح API.

جميع الحالات اصطناعية وفي صندوق محلي مغلق؛ لا تُستهدف أي منصة أو حساب أو
ثغرة حقيقية.

## قبل التشغيل

1. فعّل السرّين `ANTHROPIC_API_KEY` و`GEMINI_API_KEY` لهذا الدفتر.
2. اضغط **Run all**.
3. ارفع `PolicyFaultBench_v0.4.0_CONFIRMATORY_V1P2.zip`.
4. وافق على ربط Google Drive.
"""
    ),
    code(
        """
from google.colab import drive, files, userdata
from pathlib import Path
import hashlib, json, os, shutil, subprocess, sys, time, zipfile

drive.mount('/content/drive')
old_root = Path('/content/drive/MyDrive/PolicyFaultBench_Definitive_v1')
drive_root = Path('/content/drive/MyDrive/PolicyFaultBench_Definitive_v1_2')
drive_root.mkdir(parents=True, exist_ok=True)

uploaded = files.upload()
archives = [
    name for name in uploaded
    if name.endswith('.zip') and 'v0.4.0_CONFIRMATORY_V1P2' in name
]
assert len(archives) == 1, (
    'ارفع PolicyFaultBench_v0.4.0_CONFIRMATORY_V1P2.zip فقط'
)

work = Path('/content/pfb_v1p2_work')
if work.exists():
    shutil.rmtree(work)
work.mkdir(parents=True)
with zipfile.ZipFile(archives[0]) as archive:
    for item in archive.infolist():
        target = (work / item.filename).resolve()
        assert work.resolve() in target.parents or target == work.resolve(), (
            'مسار ZIP غير آمن'
        )
    archive.extractall(work)

root = work / 'PolicyFaultBench'
assert (root / 'pyproject.toml').is_file(), 'بنية الحزمة غير صحيحة'
print({
    'project_loaded': True,
    'version': '0.4.0',
    'checkpoint': str(drive_root),
})
"""
    ),
    code(
        """
required = ('ANTHROPIC_API_KEY', 'GEMINI_API_KEY')
env = os.environ.copy()
for name in required:
    value = userdata.get(name)
    assert value and len(value) >= 20, (
        f'السر {name} غير متاح؛ فعّل Notebook access ثم أعد الخلية'
    )
    env[name] = value
env['PFB_LIVE_ENABLED'] = 'true'
env['PFB_STUDY_ENABLED'] = 'true'
env['PYTHONPATH'] = str(root / 'src')

config_path = root / 'config' / 'experiment.json'
config = json.loads(config_path.read_text())
config['live_enabled'] = True
config['study_enabled'] = True
config['debug_only'] = True
config['models']['anthropic'] = 'claude-sonnet-5'
config['models']['gemini'] = 'gemini-3.6-flash'
study = config['definitive_study']
study['experiment_id'] = 'pfb-definitive-v1p2'
study['protocol_version'] = '1.2'
study['seed'] = 20260724
study['repetitions'] = 10
study['planned_trials_per_provider'] = 400
study['provider_delay_seconds']['anthropic'] = 0.0
study['provider_delay_seconds']['gemini'] = 15.5
config_path.write_text(json.dumps(config, indent=2) + '\\n')

manifest = json.loads((root / 'manifests' / 'owned_assets.json').read_text())
assert manifest['synthetic_only'] is True
assert manifest['public_egress'] is False
print({
    'keys_present': list(required),
    'keys_printed': False,
    'protocol_version': '1.2',
})
"""
    ),
    code(
        """
checks = [
    [sys.executable, '-m', 'unittest', 'discover',
     '-s', str(root / 'tests'), '-q'],
    [sys.executable, '-m', 'policyfaultbench.cli',
     '--root', str(root), 'validate'],
    [sys.executable, '-m', 'policyfaultbench.cli',
     '--root', str(root), 'study-plan', '--output-dir', str(drive_root)],
]
for command in checks:
    result = subprocess.run(command, env=env, text=True, capture_output=True)
    print(result.stdout)
    if result.returncode:
        print(result.stderr)
        raise RuntimeError('فشل التحقق المحلي قبل الاتصال بالنماذج')

schedule = json.loads((drive_root / 'study_schedule.json').read_text())
expected_hash = (
    '57f6535f87a7ecf0025e8ae625bb7ae3ed3aad8c8ff801e92499b6bea6ee2374'
)
assert schedule['schedule_hash'] == expected_hash, 'تغير الجدول المجمد'
print('نجحت الاختبارات والتحقق وثبات جدول الدراسة.')
"""
    ),
    markdown(
        """
## تدقيق السجلات السابقة وتصنيفها

هذه الخطوة محلية بلا تكلفة. لا توقف التنفيذ بسبب عدم مطابقة السجلين القديمين؛
بل تحفظهما منفصلين وفق تعديل البروتوكول 2.
"""
    ),
    code(
        """
audit_script = root / 'scripts' / 'audit_proposal_conformance.py'

def audit_log(label, event_log, output, require_conformant=False):
    assert event_log.is_file(), f'السجل المطلوب غير موجود: {event_log}'
    command = [
        sys.executable, str(audit_script),
        '--root', str(root),
        '--event-log', str(event_log),
        '--output', str(output),
    ]
    if require_conformant:
        command.append('--require-conformant')
    result = subprocess.run(command, env=env, text=True, capture_output=True)
    print(result.stdout)
    if result.stderr:
        print(result.stderr)
    if result.returncode:
        raise RuntimeError(f'فشل تدقيق {label}')
    report = json.loads(output.read_text())
    assert report['integrity_ok'] is True
    return report

openai_audit = audit_log(
    'OpenAI',
    root / 'study' / 'final' / 'pfb-definitive-v1-openai.jsonl',
    drive_root / 'openai_v1_conformance_audit.json',
    True,
)
assert openai_audit['audited_proposal_count'] == 400

invalidated = drive_root / 'invalidated_v1'
invalidated.mkdir(parents=True, exist_ok=True)

old_anthropic = old_root / 'pfb-definitive-v1-anthropic.jsonl'
anthropic_copy = invalidated / old_anthropic.name
assert old_anthropic.is_file(), (
    'سجل Claude القديم غير موجود في PolicyFaultBench_Definitive_v1'
)
shutil.copy2(old_anthropic, anthropic_copy)
anthropic_old_audit = audit_log(
    'Claude القديم',
    anthropic_copy,
    invalidated / 'anthropic_v1_conformance_audit.json',
)
assert anthropic_old_audit['complete_run_count'] == 400
assert anthropic_old_audit['proposal_conformance_failed'] == 109

old_gemini = old_root / 'pfb-definitive-v1-gemini.jsonl'
if not old_gemini.is_file():
    old_gemini = (
        root / 'evidence' / 'invalidated'
        / 'pfb-definitive-v1-gemini.jsonl'
    )
gemini_copy = invalidated / 'pfb-definitive-v1-gemini.jsonl'
shutil.copy2(old_gemini, gemini_copy)
gemini_old_audit = audit_log(
    'Gemini القديم',
    gemini_copy,
    invalidated / 'gemini_v1_conformance_audit.json',
)
assert gemini_old_audit['complete_run_count'] == 14
assert gemini_old_audit['proposal_conformance_failed'] == 14

for relative in (
    'config/study_protocol_amendment_1.json',
    'config/study_protocol_amendment_2.json',
    'reports/GEMINI_STOP_AUDIT_AND_AMENDMENT.md',
    'reports/PROTOCOL_AMENDMENT_2.md',
):
    source = root / relative
    shutil.copy2(source, drive_root / source.name)

print({
    'openai_retained': '400/400 exact',
    'anthropic_v1': '109/400 excluded; raw log retained',
    'gemini_v1': '14/14 excluded; raw log retained',
})
"""
    ),
    markdown(
        """
## بوابتا المطابقة

لا تبدأ الـ800 تجربة إلا بعد نجاح Claude وGemini في 12/12 حالة لكل منهما.
"""
    ),
    code(
        """
gate_script = root / 'scripts' / 'provider_conformance_gate.py'

def run_gate(provider, delay):
    output = drive_root / f'{provider}_conformance_gate_v1p2.json'
    command = [
        sys.executable, str(gate_script), provider,
        '--root', str(root),
        '--output', str(output),
        '--delay-seconds', str(delay),
    ]
    result = subprocess.run(command, env=env, text=True, capture_output=True)
    print(result.stdout)
    if result.stderr:
        print(result.stderr)
    if result.returncode:
        raise RuntimeError(
            f'فشلت بوابة {provider}؛ لم تبدأ التجربة الأساسية'
        )
    report = json.loads(output.read_text())
    assert report['gate_passed'] is True and report['passed'] == 12
    return report

anthropic_gate = run_gate('anthropic', 0.0)
gemini_gate = run_gate('gemini', 15.5)
print({'anthropic_gate': '12/12', 'gemini_gate': '12/12'})
"""
    ),
    code(
        """
def run_provider(provider, delay, max_cycles=20):
    status_path = drive_root / f'study_status_{provider}.json'
    for cycle in range(1, max_cycles + 1):
        command = [
            sys.executable, '-m', 'policyfaultbench.cli',
            '--root', str(root), 'study-run', provider,
            '--output-dir', str(drive_root),
            '--delay-seconds', str(delay),
        ]
        result = subprocess.run(
            command, env=env, text=True, capture_output=True
        )
        print(result.stdout)
        if result.stderr:
            print(result.stderr[-1500:])
        assert status_path.is_file(), f'لم يُنشأ ملف حالة {provider}'
        status = json.loads(status_path.read_text())
        print({
            'provider': provider,
            'cycle': cycle,
            'complete': status['primary_complete'],
            'remaining': status['remaining'],
            'conformance_failures':
                status['model_conformance_failure_count'],
            'containment_failures':
                status['invocation_containment_failures'],
            'cost_usd': status['completed_cost_usd'],
            'stop_reason': status['stop_reason'],
        })
        if status['invocation_containment_failures']:
            raise RuntimeError(
                f'توقف آمن: فشل احتواء بعد بوابة {provider}'
            )
        if status['remaining'] == 0:
            return status
        reason = status.get('stop_reason', '')
        if reason.startswith('transient_abort:'):
            wait_seconds = 90 if provider == 'gemini' else 45
            print(
                f'توقف عابر؛ انتظار {wait_seconds} ثانية ثم الاستئناف...'
            )
            time.sleep(wait_seconds)
            continue
        raise RuntimeError(f'توقف غير عابر في {provider}: {reason}')
    raise RuntimeError(f'تجاوز دورات الاستئناف في {provider}')

anthropic_status = run_provider('anthropic', 0.0)
gemini_status = run_provider('gemini', 15.5)
assert anthropic_status['remaining'] == 0
assert gemini_status['remaining'] == 0
print({'anthropic_complete': 400, 'gemini_complete': 400})
"""
    ),
    code(
        """
final_audits = {}
for provider in ('anthropic', 'gemini'):
    event_log = drive_root / f'pfb-definitive-v1p2-{provider}.jsonl'
    report = audit_log(
        f'{provider} 1.2',
        event_log,
        drive_root / f'{provider}_v1p2_final_audit.json',
        True,
    )
    assert report['audited_proposal_count'] == 400
    assert report['proposal_conformance_failed'] == 0
    assert report['oracle_failure_count'] == 0
    assert report['containment_failure_count'] == 0
    final_audits[provider] = report

config = json.loads(config_path.read_text())
config['live_enabled'] = False
config['study_enabled'] = False
config_path.write_text(json.dumps(config, indent=2) + '\\n')

result_manifest = {
    'schema_version': '1.0',
    'study': 'pfb-definitive-v1p2',
    'protocol_version': '1.2',
    'confirmatory_records': {
        'openai_v1': 400,
        'anthropic_v1p2': 400,
        'gemini_v1p2': 400,
    },
    'excluded_diagnostic_records': {
        'anthropic_v1': 400,
        'gemini_v1': 14,
    },
    'statuses': {
        'anthropic': anthropic_status,
        'gemini': gemini_status,
    },
    'files': {},
}
for path in sorted(drive_root.rglob('*')):
    if path.is_file():
        relative = str(path.relative_to(drive_root))
        result_manifest['files'][relative] = {
            'bytes': path.stat().st_size,
            'sha256': hashlib.sha256(path.read_bytes()).hexdigest(),
        }
(drive_root / 'RESULT_MANIFEST_V1P2.json').write_text(
    json.dumps(result_manifest, indent=2, sort_keys=True) + '\\n'
)

archive_base = '/content/PolicyFaultBench_CONFIRMATORY_V1P2_results'
archive_path = shutil.make_archive(archive_base, 'zip', drive_root)
print({
    'result_archive': archive_path,
    'send_this_file': Path(archive_path).name,
    'live_gates_relocked': True,
})
files.download(archive_path)
"""
    ),
    markdown(
        """
## الملف المطلوب

بعد الاكتمال سينزل:

`PolicyFaultBench_CONFIRMATORY_V1P2_results.zip`

أرسله هنا. إذا منع المتصفح التنزيل، افتح رمز المجلد في Colab ثم نزّل الملف
يدويًا من `/content`.
"""
    ),
]

notebook = {
    "cells": cells,
    "metadata": {
        "colab": {
            "name": "PolicyFaultBench_Colab_CONFIRMATORY_V1P2.ipynb",
            "provenance": [],
        },
        "kernelspec": {
            "display_name": "Python 3",
            "language": "python",
            "name": "python3",
        },
        "language_info": {"name": "python"},
    },
    "nbformat": 4,
    "nbformat_minor": 5,
}

output = (
    Path(__file__).resolve().parents[2]
    / "PolicyFaultBench_Colab_CONFIRMATORY_V1P2.ipynb"
)
output.write_text(
    json.dumps(notebook, indent=2, ensure_ascii=False) + "\n",
    encoding="utf-8",
)
print(output)
