"""Validate optional edge delivery inputs without exposing credentials or response bodies."""
import json
import os
from pathlib import Path
import re
import sys
import tempfile
from urllib.parse import urlsplit

CONFIG_NAME = ".backend-edge.json"
TOKEN_HEADER = "X-App-Robot-Backend-Token"
FIELDS = ("public_health_url", "public_base_url", "expected_build_sha", "ingress_required", "ingress_token")


def validate(value):
    if not isinstance(value, dict) or set(value) != set(FIELDS):
        raise ValueError("backend_edge_inputs_invalid")
    if any(not isinstance(value[key], str) for key in FIELDS):
        raise ValueError("backend_edge_inputs_invalid")
    public, base, sha, required, token = (value[key] for key in FIELDS)
    if required not in {"true", "false"}:
        raise ValueError("backend_ingress_required_invalid")
    if sha and not re.fullmatch(r"[a-f0-9]{40}", sha):
        raise ValueError("backend_build_sha_invalid")
    if public:
        parsed = urlsplit(public)
        if (parsed.scheme != "https" or not parsed.hostname or parsed.username or parsed.password
                or parsed.query or parsed.fragment or re.search(r"[\s\\]", public) or not sha):
            raise ValueError("backend_public_health_invalid")
        if parsed.port not in {None, 443}:
            raise ValueError("backend_public_health_invalid")
    if base:
        parsed = urlsplit(base)
        if (parsed.scheme != "https" or not parsed.hostname or parsed.username or parsed.password
                or parsed.query or parsed.fragment or parsed.port not in {None, 443}
                or not re.fullmatch(r"[a-zA-Z0-9._~:/%-]+", base) or base.endswith("/")):
            raise ValueError("backend_public_base_invalid")
        if public and not public.startswith(base + "/"):
            raise ValueError("backend_public_health_base_mismatch")
    if required == "true" and (not public or not base or not re.fullmatch(r"[a-zA-Z0-9_-]{43,128}", token)):
        raise ValueError("backend_ingress_configuration_required")
    return value


def environment():
    return validate({key: os.environ.get("BACKEND_" + key.upper(), "false" if key == "ingress_required" else "")
                     for key in FIELDS})


def load(path):
    path = Path(path)
    if path.is_symlink():
        raise ValueError("backend_edge_config_symlink")
    if not path.exists():
        return validate(dict(zip(FIELDS, ("", "", "", "false", ""))))
    if path.stat().st_size > 8192:
        raise ValueError("backend_edge_config_invalid")
    return validate(json.loads(path.read_text()))


def mode(value):
    if value["ingress_required"] == "true":
        return "edge"
    return "verify" if value["public_health_url"] or value["expected_build_sha"] else "legacy"


def runtime(path):
    value = load(path)["public_base_url"]
    if value:
        target = Path(path).parent / ".backend-public.env"
        if target.is_symlink():
            raise ValueError("backend_public_env_symlink")
        descriptor = os.open(target, os.O_WRONLY | os.O_CREAT | os.O_TRUNC | os.O_NOFOLLOW, 0o600)
        with os.fdopen(descriptor, "w") as output:
            os.fchmod(output.fileno(), 0o600)
            output.write("BACKEND_PUBLIC_BASE_URL=" + json.dumps(value) + "\n")


def receive(path):
    target = Path(path)
    value = validate(json.loads(sys.stdin.buffer.read(8193)))
    if target.is_symlink() or target.parent.is_symlink():
        raise ValueError("backend_edge_config_symlink")
    descriptor, temporary = tempfile.mkstemp(prefix=target.name + ".", dir=target.parent)
    try:
        with os.fdopen(descriptor, "w") as output:
            os.fchmod(output.fileno(), 0o600)
            json.dump(value, output)
            output.flush()
            os.fsync(output.fileno())
        os.replace(temporary, target)
    finally:
        Path(temporary).unlink(missing_ok=True)


def main():
    if sys.argv[1] == "check":
        environment()
    elif sys.argv[1] == "export":
        print(json.dumps(environment()))
    elif sys.argv[1] == "mode":
        print(mode(load(sys.argv[2])))
    elif sys.argv[1] == "runtime":
        runtime(sys.argv[2])
    elif sys.argv[1] == "receive":
        receive(sys.argv[2])
    else:
        raise ValueError("backend_edge_operation_invalid")


if __name__ == "__main__":
    try:
        main()
    except (OSError, ValueError):
        sys.exit("backend_edge_configuration_invalid")
