"""Route identity is shared by catalog install and the W4P bundler."""
from __future__ import annotations

import tempfile
from pathlib import Path

from src.domain.codegen.port_adapter import catalog_adapter_files
from src.domain.codegen.route_identity import (
    application_pattern,
    catalog_route_collisions,
    retire_colliding_application_routes,
)


def test_parameter_spelling_is_not_part_of_the_route():
    form_key = application_pattern("functions/api/forms/[form_key]/files.js")
    form_key_canonical = application_pattern("functions/api/forms/[formKey]/files.js")
    entity = application_pattern("functions/api/records/[entity]/facet.js")
    entity_key = application_pattern("functions/api/records/[entity_key]/facet.js")
    job = application_pattern("functions/api/jobs/[job_id].js")
    job_camel = application_pattern("functions/api/jobs/[jobId].js")
    assert form_key == form_key_canonical
    assert entity == entity_key
    assert job == job_camel
    assert form_key != entity


def test_two_catalog_files_for_one_worker_route_are_rejected():
    with tempfile.TemporaryDirectory() as raw:
        keep = {
            "functions/api/records/[entity]/facet.js",
            "functions/api/records/[entity_key]/facet.js",
        }
        try:
            retire_colliding_application_routes(raw, keep)
        except ValueError as exc:
            assert str(exc).startswith("catalog_route_collision:")
        else:
            raise AssertionError("expected catalog_route_collision")


def test_catalog_worker_routes_do_not_collide_with_each_other():
    files = catalog_adapter_files("nuxt_app", {"legacy_contact_submit": False})
    routes = {name for name in files if name.startswith("functions/api/")}
    assert catalog_route_collisions(routes) == []


def test_every_capability_alias_is_retired_when_the_catalog_owns_the_route():
    with tempfile.TemporaryDirectory() as raw:
        root = Path(raw)
        aliases = [
            "functions/api/forms/[form_key]/files.js",
            "functions/api/records/[entity_key]/facet.js",
            "functions/api/jobs/[jobId].js",
            "functions/api/imports/[sessionId]/commit.js",
            "server/api/bookings/[reservationId].get.ts",
        ]
        for rel in aliases:
            path = root / rel
            path.parent.mkdir(parents=True, exist_ok=True)
            path.write_text("export function onRequest() {}\n", encoding="utf-8")
        keep = {
            "functions/api/forms/[formKey]/files.js",
            "functions/api/records/[entity]/facet.js",
            "functions/api/jobs/[job_id].js",
            "functions/api/imports/[session_id]/commit.js",
            "server/api/bookings/[reservation_id].get.ts",
        }

        retired = retire_colliding_application_routes(raw, keep)

    for rel in aliases:
        assert not (root / rel).exists()
        assert f".p2hs/local-bak/{rel}" in retired


def test_catalog_install_retires_a_non_form_alias_before_writing():
    with tempfile.TemporaryDirectory() as raw:
        root = Path(raw)
        legacy = root / "functions/api/records/[entity_key]/facet.js"
        legacy.parent.mkdir(parents=True, exist_ok=True)
        legacy.write_text("export function onRequest() {}\n", encoding="utf-8")

        from src.domain.codegen.port_adapter import install_catalog_adapters

        result = install_catalog_adapters(
            raw,
            "html",
            {"legacy_contact_submit": False},
        )

        retired = result["retired_form_aliases"]
        assert not legacy.exists()
        assert any("records/[entity_key]/facet.js" in item for item in retired)
        assert (root / "functions/api/records/[entity]/facet.js").is_file()
