"""Tests for parent/child logger close and flush ownership semantics."""

from __future__ import annotations

import pathlib
import sys
import unittest


ROOT = pathlib.Path(__file__).resolve().parents[1]
SRC = ROOT / "src"
if str(SRC) not in sys.path:
    sys.path.insert(0, str(SRC))

from vedatrace._engine import Engine
from vedatrace.config import BatchingConfig, VedaTraceConfig
from vedatrace.logger import Logger
from vedatrace.models import LogRecord


class RecordingTransport:
    def __init__(self) -> None:
        self.batches: list[list[LogRecord]] = []
        self.close_calls = 0

    def emit(self, records: list[LogRecord]) -> None:
        self.batches.append(list(records))

    def close(self) -> None:
        self.close_calls += 1


class TestChildCloseSemantics(unittest.TestCase):
    def _make_parent_logger(self) -> tuple[Logger, Engine, RecordingTransport]:
        transport = RecordingTransport()
        config = VedaTraceConfig(
            api_key="test-key",
            service="orders",
            batching=BatchingConfig(
                enabled=True,
                batch_size=10,
                flush_interval_seconds=0.0,
            ),
            transports=[transport],
        )
        engine = Engine(config)
        parent = Logger(config, engine)
        return parent, engine, transport

    def test_child_close_does_not_close_engine_and_parent_still_logs(self) -> None:
        parent, engine, transport = self._make_parent_logger()
        child = parent.child(default_metadata={"scope": "child"})

        parent.info("before-child-close")
        self.assertEqual(len(transport.batches), 0)

        child.close()
        self.assertEqual(transport.close_calls, 0)

        parent.info("after-child-close")
        parent.flush()

        self.assertEqual(len(transport.batches), 1)
        self.assertEqual(
            [record.message for record in transport.batches[0]],
            ["before-child-close", "after-child-close"],
        )
        self.assertEqual(len(engine._test_records), 2)

    def test_child_flush_flushes_shared_engine_queue(self) -> None:
        parent, _, transport = self._make_parent_logger()
        child = parent.child(default_metadata={"scope": "child"})

        parent.info("pending")
        self.assertEqual(len(transport.batches), 0)

        child.flush()

        self.assertEqual(len(transport.batches), 1)
        self.assertEqual([record.message for record in transport.batches[0]], ["pending"])

    def test_parent_close_closes_engine_once(self) -> None:
        parent, _, transport = self._make_parent_logger()
        child = parent.child(default_metadata={"scope": "child"})

        child.close()
        self.assertEqual(transport.close_calls, 0)

        parent.close()
        parent.close()

        self.assertEqual(transport.close_calls, 1)


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