"""Python 3.10+: run on your server, never in a browser. No dependencies."""
import json
import os
import sys
from urllib.error import HTTPError, URLError
from urllib.parse import urlencode
from urllib.request import Request, urlopen


class VerificationError(Exception):
    def __init__(self, status, message, retry_after=None):
        super().__init__(message)
        self.status = status
        self.retry_after = retry_after


def verify_email(email, *, key=None, opener=urlopen):
    key = key or os.environ.get("EEV_API_KEY", "eev_sandbox_key")
    url = "https://api.easyemailverification.com/v1/verify?" + urlencode({"email": email})
    request = Request(url, headers={"X-API-Key": key, "Accept": "application/json"})
    try:
        with opener(request, timeout=30) as response:
            data = json.load(response)
    except HTTPError as error:
        messages = {402: "No credits: check your account before retrying.",
                    429: "Rate limited: wait before another request; respect Retry-After."}
        raise VerificationError(error.code, messages.get(error.code, "Verification request failed."),
                                error.headers.get("Retry-After") if error.headers else None) from error
    except (URLError, TimeoutError, ValueError) as error:
        raise VerificationError(503, "No reliable result; review the request before retrying.") from error
    if not isinstance(data, dict) or data.get("result") not in ("valid", "invalid", "unknown"):
        raise VerificationError(502, "Unexpected API response; do not classify the address.")
    return data


def classify(data):
    if data["result"] == "invalid":
        return "invalid"
    if data["result"] == "unknown":
        return "review"
    if data.get("disposable") or data.get("accept_all") or data.get("safe_to_send") is not True:
        return "review"
    return "passed_checks"


if __name__ == "__main__":
    email = sys.argv[1] if len(sys.argv) > 1 else "valid@sandbox.easyemailverification.com"
    try:
        data = verify_email(email)
        print(json.dumps({"decision": classify(data), "result": data["result"],
                          "reason": data.get("reason"), "did_you_mean": data.get("did_you_mean")}, indent=2))
    except VerificationError as error:
        print(f"HTTP {error.status}: {error}", file=sys.stderr)
        sys.exit(1)
