"""Wiring: installed entity_ingest_bindings resolve live from the pack's
composition and flow through to the generated app's runtime files.
"""
from __future__ import annotations

from uuid import uuid4

import pytest

from src.domain.codegen.entity_ingest_adapter import entity_ingest_adapter_files
from src.domain.codegen.port_adapter import catalog_adapter_files
from src.domain.codegen.runtime_contract import _installed_entity_ingest_bindings

_CONTENT_ITEM_RAW_COMPOSITION = {
    "entities": [{
        "entity_key": "content_item",
        "schema": {
            "fields": [
                {"key": "title", "type": "text"},
                {"key": "external_id", "type": "text"},
                {"key": "source", "type": "text"},
            ],
        },
    }],
}


class _Row:
    def __init__(self, **kw):
        self.__dict__.update(kw)


class _ScalarAllResult:
    def __init__(self, rows):
        self._rows = rows

    def all(self):
        return self._rows


class _ScalarsResult:
    def __init__(self, rows):
        self._rows = rows

    def scalars(self):
        return self

    def all(self):
        return self._rows


class _FakeDB:
    def __init__(self, results: list):
        self._results = list(results)

    async def execute(self, _stmt):
        return self._results.pop(0)


@pytest.mark.asyncio
async def test_resolves_bindings_for_installed_packs_only():
    pack_row = _Row(slug="content-ingest", composition=_CONTENT_ITEM_RAW_COMPOSITION)
    db = _FakeDB([
        _ScalarAllResult([("content-ingest",)]),
        _ScalarsResult([pack_row]),
    ])
    bindings = await _installed_entity_ingest_bindings(db, uuid4())
    assert bindings == [
        {
            "pack_slug": "content-ingest",
            "provider": "content_ingest",
            "forward_path": "/api/webhooks/content-ingest",
        }
    ]


@pytest.mark.asyncio
async def test_no_installed_packs_yields_empty_list():
    db = _FakeDB([_ScalarAllResult([])])
    assert await _installed_entity_ingest_bindings(db, uuid4()) == []


@pytest.mark.asyncio
async def test_installed_pack_without_entity_ingest_bindings_is_skipped():
    pack_row = _Row(slug="contact-capture", composition={"entities": [{"entity_key": "contact_submission"}]})
    db = _FakeDB([
        _ScalarAllResult([("contact-capture",)]),
        _ScalarsResult([pack_row]),
    ])
    assert await _installed_entity_ingest_bindings(db, uuid4()) == []


def test_catalog_adapter_files_installs_the_webhook_route_when_bindings_present():
    runtime_contract = {
        "routes": {"admin_panel_path": "/admin"},
        "capabilities": {
            "entity_ingest_bindings": [
                {
                    "pack_slug": "content-ingest",
                    "provider": "content_ingest",
                    "forward_path": "/api/webhooks/content-ingest",
                }
            ],
        },
        "presentation": {},
    }
    files = catalog_adapter_files(
        "html", {"ports": [], "catalog_version": 1, "runtime_contract": runtime_contract}
    )
    assert "functions/api/webhooks/content-ingest.js" in files
    assert "functions/_lib/p2hs-entity-ingest.mjs" in files
    assert files["functions/api/webhooks/content-ingest.js"] == entity_ingest_adapter_files(
        "html",
        [{
            "pack_slug": "content-ingest",
            "provider": "content_ingest",
            "forward_path": "/api/webhooks/content-ingest",
        }],
    )["functions/api/webhooks/content-ingest.js"]


def test_catalog_adapter_files_installs_nothing_when_no_bindings():
    files = catalog_adapter_files(
        "html", {"ports": [], "catalog_version": 1, "runtime_contract": {"capabilities": {}}}
    )
    assert "functions/_lib/p2hs-entity-ingest.mjs" not in files
