# Copyright (c) 2026 Nous Research
"""Channel inbox config and ingress reject untrusted Telegram updates."""

from __future__ import annotations

import pytest

from gateway.platforms.telegram_channel_inbox import (
    ChannelInboxIngressError,
    ChannelInboxMessage,
    ChannelInboxRejectReason,
    parse_channel_inbox_message,
)
from gateway.platforms.telegram_channel_inbox_config import (
    ChannelInboxConfig,
    ChannelInboxRuntimeAuthority,
)
from tests.gateway.channel_inbox_testkit import (
    AUTHORITY,
    BOT_ID,
    CANDIDATE_DIGEST,
    CAPABILITY_DIGEST,
    CHAT_ID,
    TOPIC_ID,
    ChannelMessageSpec,
    channel_message,
    config_extra,
    config_payload,
)


def test_channel_inbox_is_default_off() -> None:
    assert ChannelInboxConfig.from_extra({}) is None
    config = ChannelInboxConfig.from_extra(config_extra(enabled=False))
    assert config is not None
    assert not config.enabled
    assert parse_channel_inbox_message(channel_message(), config) is None


def test_channel_inbox_rejects_forged_capability_digest() -> None:
    payload = config_payload()
    payload["capability_digest"] = "0" * 64
    config = ChannelInboxConfig.from_extra({"nutricoach_channel_inbox": payload})
    assert config is not None
    runtime = ChannelInboxRuntimeAuthority(
        bot_id=BOT_ID,
        parent_channel_id=AUTHORITY.parent_channel_id,
        candidate_digest=CANDIDATE_DIGEST,
        can_manage_direct_messages=True,
    )

    assert not config.runtime_authorized(runtime)
    assert config.capability_digest != CAPABILITY_DIGEST


def test_channel_inbox_parses_customer_identity_from_topic() -> None:
    config = ChannelInboxConfig.from_extra(config_extra())
    assert config is not None

    ingress = parse_channel_inbox_message(channel_message(), config)

    assert ingress is not None
    assert ingress.user_id == "42"
    assert ingress.chat_id == CHAT_ID
    assert ingress.topic_id == str(TOPIC_ID)
    assert ingress.user_name == "고객"


@pytest.mark.parametrize(
    ("message", "reason"),
    [
        (
            channel_message(ChannelMessageSpec(sender_id=99)),
            ChannelInboxRejectReason.SENDER_IS_NOT_TOPIC_USER,
        ),
        (
            channel_message(ChannelMessageSpec(topic_id=0)),
            ChannelInboxRejectReason.INVALID_TOPIC,
        ),
        (
            channel_message(ChannelMessageSpec(is_direct_messages=False)),
            ChannelInboxRejectReason.NOT_DIRECT_MESSAGES_CHAT,
        ),
    ],
)
def test_channel_inbox_rejects_unsafe_ingress(
    message: ChannelInboxMessage,
    reason: ChannelInboxRejectReason,
) -> None:
    config = ChannelInboxConfig.from_extra(config_extra())
    assert config is not None

    with pytest.raises(ChannelInboxIngressError) as captured:
        parse_channel_inbox_message(message, config)

    assert captured.value.reason is reason
