import importlib.util
import json
import os
from pathlib import Path
import shutil
import subprocess
import urllib.request

os.umask(0o077)
R = Path(__file__).parent
spec = importlib.util.spec_from_file_location('gate', '/tmp/codex/ltb1021/2026-09-11_service-stop_r01/gate.py')
g = importlib.util.module_from_spec(spec)
spec.loader.exec_module(g)

def main():
    assert not (R/'preflight.json').exists()
    assert g.sh(['git', '-C', str(g.REPO), 'rev-parse', 'HEAD']).strip() == '1edaa70f3aff83f8f75876126b91968252a82e3d'
    assert not g.sh(['git', '-C', str(g.REPO), 'status', '--porcelain']).strip()
    c = g.inspect()
    env = g.load_env_file(str(g.ENV))
    overlay = Path(env['CONTEXTRA_RUNTIME_STATE_ROOT'])/'streams_runtime.yaml'
    rows = g.yaml.safe_load(overlay.read_text())['added']
    assert len(rows) == 1
    stream = rows[0]
    assert all(stream[k] is False for k in ('store', 'active_learning', 'autostart'))
    assert stream['scenarios'] == 'off' and stream['inference_profile']['roles'] == ['det']
    opener = urllib.request.build_opener(urllib.request.ProxyHandler({}))
    with opener.open('http://127.0.0.1:'+env['FASTAPI_HOST_PORT']+'/api/v1/streams', timeout=4) as response:
        status = json.load(response)['streams']
    assert len(status) == 1 and status[0]['state'] == 'stopped'
    assert g.sha(g.CFG) == '5e5a4d22786f8b5218ac821379fbec091d9e3006f62c880ee3e3da5ced2f0e0b'
    assert g.sha(g.CFG.parent/'2/model.plan') == '5fdf1e9c55ab947a3b7d5f7f6bdceaf1e36a9e52efdf86f5a15d3b99b8631d1e'
    ids = g.sh(['docker', 'ps', '-aq']).split()
    containers = json.loads(g.sh(['docker', 'inspect', *ids]))
    project = c['Config']['Labels']['com.docker.compose.project']
    redis = [x for x in containers if x['Config'].get('Labels', {}).get('com.docker.compose.project') == project
             and x['Config'].get('Labels', {}).get('com.docker.compose.service') == 'redis']
    assert len(redis) == 1
    redis = redis[0]
    def redis_read(*command):
        return g.sh(['docker', 'exec', redis['Id'], 'redis-cli', '--raw', *command], timeout=10)
    details = {name: redis_read(*cmd) for name, cmd in {
        'acl': ['ACL', 'LIST'], 'dbsize': ['DBSIZE'], 'keyspace': ['INFO', 'keyspace'],
        'clients': ['CLIENT', 'LIST'], 'policy': ['CONFIG', 'GET', 'maxmemory-policy'],
        'memory': ['CONFIG', 'GET', 'maxmemory'], 'save': ['CONFIG', 'GET', 'save'],
        'aclfile': ['CONFIG', 'GET', 'aclfile']}.items()}
    docker_root = g.sh(['docker', 'info', '--format', '{{.DockerRootDir}}']).strip()
    free = shutil.disk_usage(docker_root).free
    interfaces = json.loads(g.sh(['ip', '-j', '-4', 'address', 'show']))
    addresses = [a['local'] for i in interfaces for a in i.get('addr_info', []) if a['local'].startswith('192.168.50.')]
    firewall = {}
    for key, command in {'filter': ['iptables', '-S'], 'docker_user': ['iptables', '-S', 'DOCKER-USER'],
                         'nat': ['iptables', '-t', 'nat', '-S'], 'listeners': ['ss', '-lntH']}.items():
        p = subprocess.run(command, capture_output=True, text=True, timeout=10)
        firewall[key] = dict(code=p.returncode, stdout=p.stdout, stderr=p.stderr)
    out = dict(analytics=c, redis=redis, redis_details=details, other_containers=g.others(),
               overlay_hash=g.sha(overlay), env_hash=g.sha(g.ENV), model_hash=g.sha(g.CFG),
               plan_hash=g.sha(g.CFG.parent/'2/model.plan'), docker_root=docker_root, disk_free=free,
               gpu_mib=g.gpu(), ai_lan_candidates=addresses, firewall=firewall,
               test_readers=['192.168.50.215', '192.168.50.238'], site_reference_only='192.168.30.18')
    (R/'preflight.json').write_text(json.dumps(out, indent=2))
    print(json.dumps(dict(analytics=c['State']['Status'], health=c['State'].get('Health', {}).get('Status'),
                         stream='stopped', redis=redis['State']['Status'], redis_dbsize=details['dbsize'].strip(),
                         redis_default_nopass='nopass' in details['acl'], redis_acl_lines=len(details['acl'].splitlines()),
                         docker_free_gib=round(free/1024**3, 2), gpu_mib=out['gpu_mib'],
                         ai_lan_address_count=len(addresses), source_readers=2,
                         redis_published_ports=bool(redis['HostConfig']['PortBindings']))))

if __name__ == '__main__':
    main()
