from __future__ import annotations

import logging
from pathlib import Path
import sys
import tempfile
import unittest


SRC_ROOT = Path(__file__).resolve().parents[2] / "src"

if str(SRC_ROOT) not in sys.path:
    sys.path.insert(0, str(SRC_ROOT))


from ffx.logging_utils import (  # noqa: E402
    CONSOLE_HANDLER_NAME,
    FILE_HANDLER_NAME,
    configure_ffx_logger,
    get_ffx_logger,
)


class LoggingUtilsTests(unittest.TestCase):
    def cleanup_logger(self, logger_name: str) -> None:
        logger = logging.getLogger(logger_name)
        for handler in list(logger.handlers):
            logger.removeHandler(handler)
            handler.close()

    def test_get_ffx_logger_adds_only_one_null_handler(self):
        logger_name = "ffx-test-null-handler"
        self.cleanup_logger(logger_name)

        logger = get_ffx_logger(logger_name)
        logger = get_ffx_logger(logger_name)

        null_handlers = [
            handler for handler in logger.handlers if isinstance(handler, logging.NullHandler)
        ]
        self.assertEqual(1, len(null_handlers))

        self.cleanup_logger(logger_name)

    def test_configure_ffx_logger_reuses_named_handlers(self):
        logger_name = "ffx-test-configure-handler"
        self.cleanup_logger(logger_name)

        with tempfile.TemporaryDirectory() as tempdir:
            first_log_path = Path(tempdir) / "first.log"
            second_log_path = Path(tempdir) / "second.log"

            logger = configure_ffx_logger(
                str(first_log_path),
                logging.ERROR,
                logging.INFO,
                name=logger_name,
            )
            logger = configure_ffx_logger(
                str(second_log_path),
                logging.DEBUG,
                logging.WARNING,
                name=logger_name,
            )

            console_handlers = [
                handler for handler in logger.handlers if handler.get_name() == CONSOLE_HANDLER_NAME
            ]
            file_handlers = [
                handler for handler in logger.handlers if handler.get_name() == FILE_HANDLER_NAME
            ]

            self.assertEqual(1, len(console_handlers))
            self.assertEqual(1, len(file_handlers))
            self.assertFalse(
                any(isinstance(handler, logging.NullHandler) for handler in logger.handlers)
            )
            self.assertEqual(logging.WARNING, console_handlers[0].level)
            self.assertEqual(logging.DEBUG, file_handlers[0].level)
            self.assertEqual(str(second_log_path.resolve()), file_handlers[0].baseFilename)

        self.cleanup_logger(logger_name)


if __name__ == "__main__":
    unittest.main()
