"""email.send capability contract — catalog implements vs entitlement, manifest split."""
from __future__ import annotations

from src.domain.codegen.platform_backend import _compact_connectors
from src.domain.codegen.prompt_wrapper import _app_recipes, _P2HS_CLOUD_CONTRACT
from src.domain.connectors.catalog import (
    get_action,
    get_connector,
    slugs_implementing,
)
from src.domain.manifest.service import (
    _CONNECTOR_CATALOG_HINTS,
    _connectors_manifest_envelope,
    _email_send_capability_surface,
    _provider_action_escape_hatches,
)


def test_send_email_actions_implement_email_send_not_as_entitlement() -> None:
    for slug in ("resend.send_email", "mailgun.send_email", "ses.send_email"):
        pair = get_action(slug)
        assert pair is not None, slug
        _connector, action = pair
        assert action.implements == ("email.send",)
        assert action.required_capabilities == ("integrations.execute",)


def test_other_resend_actions_do_not_claim_email_send() -> None:
    resend = get_connector("resend")
    assert resend is not None
    extras = [a for a in resend.actions if a.slug != "resend.send_email"]
    assert extras
    for action in extras:
        assert "email.send" not in action.implements


def test_slugs_implementing_email_send() -> None:
    assert set(slugs_implementing("email.send")) == {
        "resend.send_email",
        "mailgun.send_email",
        "ses.send_email",
    }


def test_manifest_splits_capability_from_provider_actions() -> None:
    envelope = _connectors_manifest_envelope(items={})
    cap = envelope["capabilities"]["email.send"]
    assert cap["request_type"] == "email.send"
    assert cap["method"] == "POST /api/jobs/email.send"
    assert cap["role"] == "default"
    assert cap["status"] == "implemented"
    assert cap["invocable"] is True
    assert "resend.send_email" in cap["implemented_by"]
    assert envelope["provider_actions"]["resend.send_email"]["role"] == "escape_hatch"
    assert envelope["provider_actions"]["ses.send_email"]["implements"] == ["email.send"]
    assert "slack.post_message" in envelope["provider_actions"]
    assert envelope["provider_actions"]["slack.post_message"]["role"] == "escape_hatch"
    assert envelope["provider_actions"]["slack.post_message"]["implements"] == ["messaging.send"]
    assert "resend" not in envelope["catalog"]
    assert "ses" not in envelope["catalog"]
    assert "mailgun" not in envelope["catalog"]


def test_catalog_hints_do_not_advertise_vendor_email_slugs() -> None:
    for connector in _CONNECTOR_CATALOG_HINTS.values():
        actions = connector.get("actions") or []
        assert "resend.send_email" not in actions
        assert "mailgun.send_email" not in actions
        assert "ses.send_email" not in actions
    assert "email.send" in _CONNECTOR_CATALOG_HINTS["twilio"]["setup"]


def test_capability_surface_and_escape_hatches_are_stable() -> None:
    from src.domain.connectors.catalog import slugs_implementing

    surface = _email_send_capability_surface()
    hatches = _provider_action_escape_hatches()
    from src.domain.connectors.invoke_capabilities import INVOKE_CAPABILITIES, is_implemented
    expected = {slug for capability in INVOKE_CAPABILITIES if is_implemented(capability)
                for slug in slugs_implementing(capability)}
    assert expected <= set(hatches)
    from src.domain.connectors.invoke_capabilities import PROVIDER_ACTION_WHEN
    extra = set(hatches) - expected
    assert extra <= set(PROVIDER_ACTION_WHEN)
    assert set(surface["implemented_by"]) <= set(hatches)
    assert all(h["role"] == "escape_hatch" for h in hatches.values())


def test_compact_connectors_keep_capability_not_vendor_schemas() -> None:
    compact = _compact_connectors(_connectors_manifest_envelope(items={"resend": {"actions": []}}))
    assert compact["capabilities"]["email.send"]["request_type"] == "email.send"
    assert compact["connected"] == ["resend"]
    assert compact["provider_actions"]["resend.send_email"]["role"] == "escape_hatch"
    assert "input_schema" not in compact["provider_actions"]["resend.send_email"]
    assert compact["capabilities"]["messaging.send"]["role"] == "default"
    assert compact["capabilities"]["messaging.send"]["status"] == "implemented"
    assert compact["provider_actions"]["slack.post_message"]["role"] == "escape_hatch"
    assert "adapter_mappings" not in compact["capabilities"]["messaging.send"]
    assert "input_schema" not in compact["capabilities"]["messaging.send"]


def test_codegen_prompt_prefers_email_send_over_vendor_slugs() -> None:
    recipes = _app_recipes()
    assert "POST /api/jobs/email.send" in recipes
    assert "escape hatch" in recipes
    assert "resend.send_email" in recipes
    assert "must not change generated code" in recipes
    assert "email.send" in _P2HS_CLOUD_CONTRACT
    assert "escape hatch" in _P2HS_CLOUD_CONTRACT
