from __future__ import annotations

import logging
import os
import time

import pytest

from pulselog.handler import PulseHandler


class TestPulseHandler:
    def setup_method(self):
        os.environ["CI"] = "true"

    def teardown_method(self):
        os.environ.pop("CI", None)

    def test_emit_info(self):
        received = []
        handler = PulseHandler("handler-test", dashboard=False)
        handler._logger._worker._handlers.append(received.extend)

        record = logging.LogRecord(
            name="test", level=logging.INFO,
            pathname="", lineno=0, msg="stdlib info",
            args=(), exc_info=None,
        )
        handler.emit(record)
        handler._logger.flush()
        time.sleep(0.1)

        assert any(r.msg == "stdlib info" for r in received)
        handler._logger.shutdown()

    def test_emit_all_levels(self):
        received = []
        handler = PulseHandler("handler-levels", dashboard=False, level="DEBUG")
        handler._logger._worker._handlers.append(received.extend)

        level_map = {
            logging.DEBUG:    "debug msg",
            logging.INFO:     "info msg",
            logging.WARNING:  "warning msg",
            logging.ERROR:    "error msg",
            logging.CRITICAL: "critical msg",
        }
        for levelno, msg in level_map.items():
            rec = logging.LogRecord(
                name="t", level=levelno, pathname="", lineno=0,
                msg=msg, args=(), exc_info=None,
            )
            handler.emit(rec)

        handler._logger.flush()
        time.sleep(0.1)

        msgs = {r.msg for r in received}
        for msg in level_map.values():
            assert msg in msgs, f"Missing: {msg}"

        handler._logger.shutdown()

    def test_unknown_level_falls_back_to_info(self):
        received = []
        handler = PulseHandler("handler-unk", dashboard=False)
        handler._logger._worker._handlers.append(received.extend)

        # Use a non-standard level number
        record = logging.LogRecord(
            name="t", level=99, pathname="", lineno=0,
            msg="unknown level", args=(), exc_info=None,
        )
        handler.emit(record)
        handler._logger.flush()
        time.sleep(0.1)

        assert any(r.msg == "unknown level" for r in received)
        handler._logger.shutdown()

    def test_handler_integrates_with_stdlib_logger(self):
        received = []
        pulse_handler = PulseHandler("stdlib-e2e", dashboard=False)
        pulse_handler._logger._worker._handlers.append(received.extend)
        pulse_handler.setLevel(logging.DEBUG)

        root = logging.getLogger("pulselog.test.stdlib")
        root.addHandler(pulse_handler)
        root.setLevel(logging.DEBUG)

        try:
            root.info("via stdlib")
            pulse_handler._logger.flush()
            time.sleep(0.1)
            assert any("via stdlib" in r.msg for r in received)
        finally:
            root.removeHandler(pulse_handler)
            pulse_handler._logger.shutdown()
