from argparse import Namespace
import yaml

from different_wrapping.challenge import Challenge
from different_wrapping.yamlyaml import generate_challenge_ingresses


def _write_compose(tmp_path, services):
    """Write a version 3 docker-compose.yml and return a Challenge parsed from it."""
    compose = {"version": "3", "services": services}
    compose_file = tmp_path / "docker-compose.yml"
    with compose_file.open("w") as f:
        yaml.dump(compose, f)
    return Challenge(tmp_path)


def test_generate_challenge_ingresses_http(tmp_path):
    """HTTP expose_type produces an HTTPRoute written to the output file."""
    challenge = _write_compose(
        tmp_path,
        {
            "web": {
                "image": "nginx:latest",
                "ports": ["80"],
                "labels": ["no.tghack.expose_type=http"],
            }
        },
    )

    args = Namespace(
        ingress_type="gateway",
        dns_host="example.com",
        gateway_parent_name="main-gw",
        gateway_parent_namespace="infra",
    )

    outdir = tmp_path / "out"
    outdir.mkdir()
    generate_challenge_ingresses(challenge, outdir, args)

    outfile = outdir / "different-wrapping-ingress.yaml"
    assert outfile.exists()

    docs = list(yaml.safe_load_all(outfile.read_text()))
    assert len(docs) == 1

    route = docs[0]
    assert route["kind"] == "HTTPRoute"
    assert route["apiVersion"] == "gateway.networking.k8s.io/v1"
    assert route["metadata"]["name"] == f"gateway-{challenge.safe_name()}-web"

    parent = route["spec"]["parentRefs"][0]
    assert parent["name"] == "main-gw"
    assert parent["namespace"] == "infra"

    assert route["spec"]["hostnames"] == [f"web-{challenge.safe_name()}.example.com"]
    backend = route["spec"]["rules"][0]["backendRefs"][0]
    assert backend["name"] == "web"
    assert backend["port"] == 80


def test_generate_challenge_ingresses_tcp(tmp_path):
    """TCP expose_type produces an XListenerSet and a TCPRoute."""
    challenge = _write_compose(
        tmp_path,
        {
            "server": {
                "image": "challserver:latest",
                "ports": ["1337"],
                "labels": ["no.tghack.expose_type=tcp"],
            }
        },
    )

    args = Namespace(
        ingress_type="gateway",
        dns_host="ctf.example.com",
        tcp_xlistenerset_gateway_name="tcp-gateway",
    )

    outdir = tmp_path / "out"
    outdir.mkdir()
    generate_challenge_ingresses(challenge, outdir, args)

    outfile = outdir / "different-wrapping-ingress.yaml"
    assert outfile.exists()

    docs = list(yaml.safe_load_all(outfile.read_text()))
    assert len(docs) == 2

    xlistenerset = docs[0]
    tcproute = docs[1]

    assert xlistenerset["kind"] == "XListenerSet"
    assert xlistenerset["spec"]["parentRef"]["name"] == "tcp-gateway"
    listener = xlistenerset["spec"]["listeners"][0]
    assert listener["protocol"] == "TCP"
    assert listener["port"] == 1337

    assert tcproute["kind"] == "TCPRoute"
    assert tcproute["metadata"]["name"] == f"tcproute-{challenge.safe_name()}-server"
    backend = tcproute["spec"]["rules"][0]["backendRefs"][0]
    assert backend["name"] == "server"
    assert backend["port"] == 1337
