"""One direct OR one explicit proxy request; proxy secret is sent via stdin, not argv."""
import ipaddress
import json
import os
import subprocess
import sys
from urllib.parse import urlsplit

def connection():
    product = os.environ.get("QG_PRODUCT", "static").lower()
    if product not in ("static", "shield"):
        raise ValueError("QG_PRODUCT must be static or shield")
    shield = product == "shield"
    key = "QUOTAGUARDSHIELD_URL" if shield else "QUOTAGUARDSTATIC_URL"
    raw = os.environ.get(key, "")
    u = urlsplit(raw)
    if not (u.scheme == ("https" if shield else "http") and
            u.port == (9294 if shield else 9293) and u.hostname and
            u.username and u.password and not u.query and not u.fragment
            and u.path in ("", "/")):
        raise ValueError("Invalid dashboard proxy connection")
    return raw

def config(mode):
    if mode == 'direct':
        return 'proxy = ""\nnoproxy = "*"\n'
    value = connection()
    if any(ord(c) < 32 or ord(c) == 127 for c in value):
        raise ValueError('Invalid proxy connection')
    value = value.replace('\\', '\\\\').replace('"', '\\"')
    return 'proxy = "' + value + '"\nnoproxy = ""\n'

def run(mode):
    if mode not in ('direct', 'proxy'):
        raise ValueError('Choose direct or proxy')
    pair = [str(ipaddress.IPv4Address(x.strip()))
            for x in os.environ.get('QG_EXPECTED_IPS', '').split(',')]
    if len(set(pair)) != 2 or len(pair) != 2:
        raise ValueError('Two dashboard IPv4 addresses required')
    r = subprocess.run(['curl', '-q', '--config', '-', '--globoff', '--silent',
                        '--fail', '--connect-timeout', '10', '--max-time', '30',
                        '--write-out', '\nQG_HTTP %{http_code}\n',
                        '--url', 'https://ip.quotaguard.com'],
                       input=config(mode), capture_output=True, text=True, check=True)
    body, marker, status = r.stdout.rpartition('\nQG_HTTP ')
    if not marker or status.strip() != '200':
        raise RuntimeError('IP check did not return HTTP 200')
    observed = str(ipaddress.IPv4Address(json.loads(body)['ip']))
    matches = observed in pair
    if mode == 'proxy' and not matches:
        raise RuntimeError('Wrong proxy egress')
    return {'client': 'curl', 'route': mode, 'http_status': 200, 'matches_dashboard_pair': matches}

if __name__ == '__main__':
    try:
        print(json.dumps(run(sys.argv[1] if len(sys.argv) > 1 else 'proxy')))
    except subprocess.CalledProcessError as error:
        hints = {5: 'Proxy DNS failed; check assigned hostname and permitted DNS route.',
                 7: 'Connection failed; check host/port, reachability and runtime policy.',
                 22: 'HTTP error; proxy or destination may have rejected the request.',
                 56: 'Receive/CONNECT failure; check authentication, policy and client compatibility.'}
        hint = hints.get(error.returncode, 'Check the selected client, TLS trust and permitted route.')
        raise SystemExit(f'curl exit {error.returncode}: {hint}') from None
    except (ValueError, KeyError):
        raise SystemExit('Check product, assigned connection and both dashboard IPv4 addresses; IP response must be valid JSON.') from None
    except OSError:
        raise SystemExit('curl could not start; check that it is installed in this execution runtime.') from None
    except Exception:
        raise SystemExit('IP check failed: require HTTP 200 and a dashboard-pair IP; review the selected route.') from None
