"""
Integration tests for ntfy topics.
"""

import json
import time
import urllib.request

import pytest


@pytest.mark.integration
@pytest.mark.ntfy
class TestNtfyTopics:
    def test_cc_cmd_topic_exists_and_writable(self):
        """Verify C&C CMD topic exists and accepts messages."""
        from engine.config import NTFY_CC_CMD_TOPIC

        topic_url = NTFY_CC_CMD_TOPIC.replace("/json", "")
        test_message = f"test_{int(time.time())}"

        req = urllib.request.Request(
            topic_url,
            data=test_message.encode("utf-8"),
            headers={
                "User-Agent": "mainline-test/0.1",
                "Content-Type": "text/plain",
            },
            method="POST",
        )

        try:
            with urllib.request.urlopen(req, timeout=10) as resp:
                assert resp.status == 200
        except Exception as e:
            raise AssertionError(f"Failed to write to C&C CMD topic: {e}") from e

    def test_cc_resp_topic_exists_and_writable(self):
        """Verify C&C RESP topic exists and accepts messages."""
        from engine.config import NTFY_CC_RESP_TOPIC

        topic_url = NTFY_CC_RESP_TOPIC.replace("/json", "")
        test_message = f"test_{int(time.time())}"

        req = urllib.request.Request(
            topic_url,
            data=test_message.encode("utf-8"),
            headers={
                "User-Agent": "mainline-test/0.1",
                "Content-Type": "text/plain",
            },
            method="POST",
        )

        try:
            with urllib.request.urlopen(req, timeout=10) as resp:
                assert resp.status == 200
        except Exception as e:
            raise AssertionError(f"Failed to write to C&C RESP topic: {e}") from e

    def test_message_topic_exists_and_writable(self):
        """Verify message topic exists and accepts messages."""
        from engine.config import NTFY_TOPIC

        topic_url = NTFY_TOPIC.replace("/json", "")
        test_message = f"test_{int(time.time())}"

        req = urllib.request.Request(
            topic_url,
            data=test_message.encode("utf-8"),
            headers={
                "User-Agent": "mainline-test/0.1",
                "Content-Type": "text/plain",
            },
            method="POST",
        )

        try:
            with urllib.request.urlopen(req, timeout=10) as resp:
                assert resp.status == 200
        except Exception as e:
            raise AssertionError(f"Failed to write to message topic: {e}") from e

    def test_cc_cmd_topic_readable(self):
        """Verify we can read messages from C&C CMD topic."""
        from engine.config import NTFY_CC_CMD_TOPIC

        test_message = f"integration_test_{int(time.time())}"
        topic_url = NTFY_CC_CMD_TOPIC.replace("/json", "")

        req = urllib.request.Request(
            topic_url,
            data=test_message.encode("utf-8"),
            headers={
                "User-Agent": "mainline-test/0.1",
                "Content-Type": "text/plain",
            },
            method="POST",
        )

        try:
            urllib.request.urlopen(req, timeout=10)
        except Exception as e:
            raise AssertionError(f"Failed to write to C&C CMD topic: {e}") from e

        time.sleep(1)

        poll_url = f"{NTFY_CC_CMD_TOPIC}?poll=1&limit=1"
        req = urllib.request.Request(
            poll_url,
            headers={"User-Agent": "mainline-test/0.1"},
        )

        try:
            with urllib.request.urlopen(req, timeout=10) as resp:
                body = resp.read().decode("utf-8")
                if body.strip():
                    data = json.loads(body.split("\n")[0])
                    assert isinstance(data, dict)
        except Exception as e:
            raise AssertionError(f"Failed to read from C&C CMD topic: {e}") from e

    def test_topics_are_different(self):
        """Verify C&C CMD/RESP and message topics are different."""
        from engine.config import NTFY_CC_CMD_TOPIC, NTFY_CC_RESP_TOPIC, NTFY_TOPIC

        assert NTFY_CC_CMD_TOPIC != NTFY_TOPIC
        assert NTFY_CC_RESP_TOPIC != NTFY_TOPIC
        assert NTFY_CC_CMD_TOPIC != NTFY_CC_RESP_TOPIC
        assert "_cc_cmd" in NTFY_CC_CMD_TOPIC
        assert "_cc_resp" in NTFY_CC_RESP_TOPIC
