#!/usr/bin/env python3
"""Exactly one HTTPS GET. No redirects, retry loop, secret argv, or body output."""
import ipaddress
import json
import os
import subprocess
import sys
from urllib.parse import urlsplit


class IPCheckTokenError(ValueError):
    """Destination credentials must not be sent to the public IP check."""


class EgressMismatchError(RuntimeError):
    """A valid IP response is outside the configured dashboard pair."""


def config(env):
    proxy = env["QUOTAGUARDSTATIC_URL"]
    target = env.get("QG_TARGET_URL", "https://ip.quotaguard.com")
    token = env.get("DESTINATION_API_TOKEN", "")
    for value in (proxy, target, token):
        if any(ord(c) < 32 or ord(c) == 127 for c in value):
            raise ValueError("Control character")
    p, t = urlsplit(proxy), urlsplit(target)
    if p.scheme not in ("http", "https") or not p.hostname or not p.username or not p.password:
        raise ValueError("Use the complete dashboard HTTP(S) connection URL")
    if p.path not in ("", "/") or p.query or p.fragment:
        raise ValueError("Invalid proxy URL")
    if t.scheme != "https" or not t.hostname or t.username or t.password or t.fragment:
        raise ValueError("Target must be a trusted HTTPS URL without userinfo or fragment")
    # JSON string quoting is compatible with curl config escapes used here.
    lines = ["silent", "show-error", "fail", "globoff", "noproxy = \"\"",
             "connect-timeout = 10", "max-time = 30", "retry = 0",
             "proxy = " + json.dumps(proxy), "url = " + json.dumps(target)]
    if token:
        if t.hostname.lower() == "ip.quotaguard.com":
            raise IPCheckTokenError("Do not send destination API tokens to an IP check")
        lines.append("header = " + json.dumps("Authorization: Bearer " + token))
    lines.append('write-out = "\\n%{http_code}"')
    return "\n".join(lines) + "\n", t.hostname == "ip.quotaguard.com"


def main():
    try:
        cfg, ip_check = config(os.environ)
        if ip_check:
            expected = {str(ipaddress.IPv4Address(os.environ[key])) for key in ("QG_IP_1", "QG_IP_2")}
            if len(expected) != 2:
                raise ValueError("Two distinct dashboard IPv4 addresses required")
        clean = {k: v for k, v in os.environ.items()
                 if not any(s in k.upper() for s in ("PROXY", "TOKEN", "SECRET", "PASSWORD", "QUOTAGUARD"))}
        # -q must be first: ignore .curlrc, which could add URLs/retries/trace.
        result = subprocess.run(["curl", "-q", "--config", "-"], input=cfg,
                                text=True, capture_output=True, timeout=35, env=clean)
        if result.returncode:
            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 transport compatibility."}
            hint = hints.get(result.returncode, "Check client transport, TLS trust and the permitted route.")
            print(f"curl exit {result.returncode}: {hint}", file=sys.stderr)
            return 1
        body, status = result.stdout.rsplit("\n", 1)
        if not 200 <= int(status) < 300:
            raise RuntimeError("Unexpected status")
        if ip_check:
            if int(status) != 200:
                raise RuntimeError("IP check requires HTTP 200")
            observed = str(ipaddress.IPv4Address(json.loads(body)["ip"]))
            if observed not in expected:
                raise EgressMismatchError("Unexpected egress")
            print("PASS: HTTP 200; egress matches a dashboard IP")
        else:
            print("PASS: destination returned a successful HTTP status")
    except EgressMismatchError:
        print("Egress mismatch: the returned IP is outside the configured dashboard pair. "
              "Check the execution route and selected subscription.", file=sys.stderr)
        return 1
    except IPCheckTokenError:
        print("IP check rejects DESTINATION_API_TOKEN. Run: env -u DESTINATION_API_TOKEN "
              "QG_TARGET_URL=https://ip.quotaguard.com python3 qg-curl.py", file=sys.stderr)
        return 1
    except Exception:
        print("Request or egress check failed. Check configuration and the guide; no response or secret was printed.", file=sys.stderr)
        return 1
    return 0


if __name__ == "__main__":
    sys.exit(main())
