# retoor <retoor@molodetz.nl>
import argparse
import ipaddress
import socket
import sys
from urllib.parse import urlsplit


def addresses(host, port):
    return {info[4][0] for info in socket.getaddrinfo(host, port, proto=socket.IPPROTO_TCP)}


def is_public_ip(value):
    ip = ipaddress.ip_address(value)
    if isinstance(ip, ipaddress.IPv6Address) and ip.ipv4_mapped is not None:
        ip = ip.ipv4_mapped
    return not (ip.is_private or ip.is_loopback or ip.is_link_local or ip.is_reserved or ip.is_multicast or ip.is_unspecified)


def check_url(url):
    parts = urlsplit(url)
    if parts.scheme not in ("http", "https"):
        raise ValueError(f"refused scheme in {url}")
    if not parts.hostname:
        raise ValueError(f"missing host in {url}")
    try:
        found = addresses(parts.hostname, parts.port or 443)
    except socket.gaierror as exc:
        raise ValueError(f"cannot resolve host in {url}") from exc
    bad = sorted(addr for addr in found if not is_public_ip(addr))
    if bad:
        raise ValueError(f"host in {url} resolves to non-public addresses: {', '.join(bad)}")
    return sorted(found)


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Refuse URLs resolving to non-public addresses.")
    parser.add_argument("url", help="URL whose host must resolve to public addresses only")
    args = parser.parse_args()
    try:
        resolved = check_url(args.url)
    except ValueError as exc:
        print(f"REFUSED: {exc}")
        sys.exit(1)
    print(f"OK: {', '.join(resolved)}")
