import hashlib
import json
import os
from pathlib import Path
import shutil
import subprocess
import time
import urllib.request

ROOT = Path(__file__).parent
REPO = Path('/workspace/contextra-analytics-runtime-lifecycle-refactor')
GATEWAY = 'contextra-ai-gateway-1'
os.umask(0o077)


def command(args, **kwargs):
    return subprocess.run(args, check=True, capture_output=True, text=True,
                          timeout=10, **kwargs).stdout


def gateway(*args):
    return command(['docker', 'exec', GATEWAY, *args])


def digest(value):
    return hashlib.sha256(value.encode()).hexdigest()


def save(name, value):
    with (ROOT / name).open('x') as target:
        json.dump(value, target, indent=2)


def snapshot():
    containers = {}
    for name in ('contextra-analytics-1', 'contextra-ai-control-sidecar-1', GATEWAY):
        value = json.loads(command(['docker', 'inspect', name]))[0]
        containers[name] = dict(id=value['Id'], image=value['Image'],
                                pid=value['State']['Pid'], started=value['State']['StartedAt'])
    with urllib.request.urlopen('http://127.0.0.1:35000/api/v1/streams', timeout=5) as response:
        streams = json.load(response)['streams']
    active = [dict(stream=row['stream_id'], run=row['run_id'], state=row['state'],
                   children={k:v.get('child_pid') for k,v in row.get('provider_processes', {}).items()})
              for row in streams if row['state'] != 'stopped']
    return dict(containers=containers, active=active)


assert shutil.disk_usage('/').free > 15 * 1024**3
before = snapshot()
old = gateway('cat', '/tmp/nginx.conf')
access = gateway('cat', '/tmp/media-access.conf')
template = (REPO / 'docker/secure-gateway.conf.template').read_text()
assert template == gateway('cat', '/etc/bridge/nginx.conf.template')
old_rule = '(?:INTRUSION|LOITERING|FIRE|FALL|FIGHT)'
new_rule = '(?:INTRUSION|LOITERING|FIRE|FALL|FIGHT|CROWD)'
assert old.count(old_rule) == 1 and old.count(new_rule) == 0
with (ROOT / 'nginx-before.conf').open('x') as target:
    target.write(old)
save('before.json', before)
candidate = '/tmp/nginx-crowd-20260928.conf'
gateway('sh', '-c', "envsubst '${AI_CONTROL_HOST_PORT}' < /etc/bridge/nginx.conf.template > " + candidate)
rendered = gateway('cat', candidate)
assert rendered == old.replace(old_rule, new_rule)
gateway('nginx', '-t', '-c', candidate)
assert old == gateway('cat', '/tmp/nginx.conf')
assert access == gateway('cat', '/tmp/media-access.conf')
gateway('mv', candidate, '/tmp/nginx.conf')
gateway('nginx', '-s', 'reload', '-c', '/tmp/nginx.conf')
time.sleep(2)
gateway('nginx', '-t', '-c', '/tmp/nginx.conf')
assert gateway('cat', '/tmp/nginx.conf') == rendered
assert gateway('cat', '/tmp/media-access.conf') == access
after = snapshot()
assert before['containers'] == after['containers']
result = dict(before=before, after=after, template_sha256=digest(template),
              rendered_sha256=digest(rendered), previous_sha256=digest(old),
              nginx_check=True, reload=True, containers_unchanged=True,
              active_channels_unchanged=before['active'] == after['active'],
              access_policy_unchanged=True, live_media_request_performed=False,
              manual_browser_acceptance='user_followup', python312_targeted_tests_passed=19)
save('reflection.json', result)
print(json.dumps({k:v for k,v in result.items() if k not in ('before','after')}, indent=2))
