"""Fail-closed Prometheus release gate. Run only after a full new-release window."""
import json
import math
import os
import time
import urllib.parse
import urllib.request


def query(metric):
    expression = metric if metric.startswith('min(') else metric + '{release="orders",track="candidate"}'
    url = os.environ['PROM_URL'].rstrip('/') + '/api/v1/query?' + urllib.parse.urlencode({'query': expression})
    headers = {}
    if os.environ.get('PROM_TOKEN'):
        if not url.startswith('https://'):
            raise ValueError('Token requires HTTPS')
        headers['Authorization'] = 'Bearer ' + os.environ['PROM_TOKEN']
    with urllib.request.urlopen(urllib.request.Request(url, headers=headers), timeout=15) as response:
        data = json.load(response)
    if data['status'] != 'success' or data['data']['resultType'] != 'vector':
        raise ValueError('Invalid query result')
    results = data['data']['result']
    if len(results) != 1:
        raise ValueError('Expected exactly one series')
    timestamp, value = results[0]['value']
    value = float(value)
    if not math.isfinite(value) or not 0 <= time.time() - float(timestamp) <= 120:
        raise ValueError('Non-finite or stale metric')
    return value


def main():
    # Raw target health blocks progress when recording rules still see older samples.
    healthy = query('min(up{namespace="orders",track="candidate"})')
    count = query('release_requests_10m')
    errors = query('release_error_ratio_10m')
    latency = query('release_p95_seconds_10m')
    if not (healthy == 1 and count >= 1000 and 0 <= errors <= 0.01 and 0 <= latency <= 0.5):
        raise SystemExit('FAIL: release gate')
    print('PASS: technical metrics; business reconciliation is also required')


if __name__ == '__main__':
    main()
