from __future__ import annotations

import contextlib
import io
import json
import logging
import os
import unittest
from unittest.mock import patch

from src.errors import UserError
from src.logging_setup import configure_logging, log_event


class TestLogging(unittest.TestCase):
    def test_json_logging_emits_json(self) -> None:
        buf = io.StringIO()
        with patch.dict(os.environ, {"EVENTFOTO_LOG_JSON": "1"}, clear=True):
            with contextlib.redirect_stderr(buf):
                enabled = configure_logging(cli_log_json=None)
                self.assertTrue(enabled)
                logger = logging.getLogger("test.logger")
                log_event(logger, "test.event", foo="bar")

        lines = [line for line in buf.getvalue().splitlines() if line.strip()]
        self.assertEqual(len(lines), 1)
        payload = json.loads(lines[0])
        self.assertEqual(payload["event"], "test.event")
        self.assertEqual(payload["foo"], "bar")
        self.assertEqual(payload["level"], "INFO")
        self.assertEqual(payload["logger"], "test.logger")

    def test_json_logging_off_by_default(self) -> None:
        buf = io.StringIO()
        with patch.dict(os.environ, {}, clear=True):
            with contextlib.redirect_stderr(buf):
                enabled = configure_logging(cli_log_json=None)
                self.assertFalse(enabled)
                logger = logging.getLogger("test.logger")
                log_event(logger, "test.event", foo="bar")
        self.assertFalse(buf.getvalue().strip())

    def test_invalid_log_json_env_fails_closed(self) -> None:
        with patch.dict(os.environ, {"EVENTFOTO_LOG_JSON": "maybe"}, clear=True):
            with self.assertRaises(UserError):
                configure_logging(cli_log_json=None)
