"""B2FGTAFA isolated producer. Launch only after Doyle's explicit END."""
import argparse
import json
import os
from pathlib import Path
import shutil
import subprocess
import time

ROOT = Path(r'C:\Users\decid\Documents\projects\spt-core')
HERE = Path(__file__).resolve().parent
TREE = ROOT / '.worktrees/hertz-304-phase-b'
TARGET = TREE / 'target'
LAUNCHER = ROOT / '.spt/preserved/hertz-fp-driver-review/d2/field-rig-r5-S6ESSJ3N/support/fp-bin/launch-v2.ps1'
CARGO = shutil.which('cargo')
PWSH = shutil.which('pwsh')
FILTERS = {
    'both': '(binary(=rc_attach_truth) & test(=harness_only_refuses_truthfully_pre_stream)) | binary(=restart_replay_lifetime)',
    'registry': 'binary(=rc_attach_truth) & test(=harness_only_refuses_truthfully_pre_stream)',
    'replay': 'binary(=restart_replay_lifetime)',
}
SCOPE = ['-p', 'spt', '-p', 'spt-daemon', '--test', 'rc_attach_truth', '--test', 'restart_replay_lifetime']

def save(path, value):
    with path.open('x', encoding='utf-8', newline='\n') as f:
        json.dump(value, f, indent=2)
        f.write('\n')

def run(label, argv, seconds, mode):
    dest = HERE / label
    dest.mkdir()
    env = dict(os.environ)
    before = sorted(k for k in env if k.upper().startswith(('SPT_', 'OWL_')))
    for k in list(env):
        if k.upper().startswith(('SPT_', 'OWL_')) or k.upper() in ('CARGO_TARGET_DIR', 'RUSTFLAGS', 'HERTZ_PHASE_B_MODE'):
            env.pop(k)
    env['CARGO_TARGET_DIR'] = str(TARGET)
    overlay = {} if mode == 'original' else {'HERTZ_PHASE_B_MODE': mode}
    save(dest / 'argv.json', argv)
    save(dest / 'environment.json', overlay)
    save(dest / 'environment-names.json', {
        'before': before,
        'after': sorted(k for k in env if k.upper().startswith(('SPT_', 'OWL_'))),
        'target': str(TARGET),
        'fixture_mode': mode,
        'parent_environment_unchanged': True,
    })
    command = [PWSH, '-NoProfile', '-File', str(LAUNCHER), '-Label', label,
               '-Seconds', str(seconds), '-Scope', 'step', '-Admission', 'process-tree',
               '-RecordFile', str(dest / 'native.json'), '-ArgsFile', str(dest / 'argv.json'),
               '-Exe', CARGO, '-OutFile', str(dest / 'stdout.log'), '-ErrFile', str(dest / 'stderr.log'),
               '-EnvironmentFile', str(dest / 'environment.json'), '-StopFile', str(dest / 'stop')]
    save(dest / 'command.json', {'argv': command, 'cwd': str(TREE)})
    free_start = shutil.disk_usage(ROOT).free
    minimum_free = free_start
    started = time.monotonic()
    reason = None
    with (dest / 'launcher.log').open('xb') as log:
        proc = subprocess.Popen(command, cwd=TREE, env=env, stdin=subprocess.DEVNULL, stdout=log, stderr=subprocess.STDOUT)
        while proc.poll() is None:
            free = shutil.disk_usage(ROOT).free
            minimum_free = min(minimum_free, free)
            if reason is None and (free <= 32 * 1024**3 or free_start - free >= 64 * 1024**3):
                reason = 'disk_floor_or_growth_limit'
                with (dest / 'stop').open('x') as f:
                    f.write(reason)
            time.sleep(1)
        launcher_exit = proc.wait()
    native = json.loads((dest / 'native.json').read_text(encoding='utf-8-sig'))
    stderr = (dest / 'stderr.log').read_text(encoding='utf-8-sig', errors='replace')
    summary = [line.strip() for line in stderr.splitlines() if 'Summary [' in line]
    result = {
        'label': label, 'mode': mode, 'launcher_exit': launcher_exit,
        'native_exit': native['subject']['native_exit'],
        'completion_reason': native['completion_reason'], 'coverage': native['coverage'],
        'termination': native['termination'], 'active_processes': native['job']['active_processes'],
        'elapsed_seconds': time.monotonic() - started, 'summary': summary,
        'start_free_bytes': free_start, 'minimum_free_bytes': minimum_free,
        'stop_reason': reason,
    }
    save(dest / 'result.json', result)
    print(json.dumps(result), flush=True)
    if native['coverage'] != 'COMPLETE' or native['termination'] != 'CONFIRMED_GONE' or reason:
        raise RuntimeError('PRODUCER_CONTAINMENT_OR_RESOURCE_REFUSAL')
    return result

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('action', choices=['build', 'cohort'])
    parser.add_argument('--label', required=True)
    parser.add_argument('--selector', choices=FILTERS, default='both')
    parser.add_argument('--mode', default='original')
    parser.add_argument('--count', type=int, default=5)
    args = parser.parse_args()
    if not CARGO or not PWSH:
        raise RuntimeError('REQUIRED_EXECUTABLE_ABSENT')
    if args.action == 'build':
        argv = ['nextest', 'list'] + SCOPE + ['--profile', 'ci-windows', '-E', FILTERS[args.selector], '--message-format', 'json']
        result = run(args.label, argv, 2400, args.mode)
        raise SystemExit(0 if result['native_exit'] == 0 else 1)
    results = []
    for n in range(1, args.count + 1):
        argv = ['nextest', 'run'] + SCOPE + ['--profile', 'ci-windows', '-E', FILTERS[args.selector],
                '--retries', '0', '--no-fail-fast', '--success-output', 'immediate', '--failure-output', 'immediate', '--color', 'never']
        result = run(f'{args.label}-{n:02}', argv, 180, args.mode)
        results.append(result)
        if result['native_exit'] not in (0, 100):
            break
    save(HERE / (args.label + '-cohort.json'), results)
