import os
import tempfile
import unittest
import uuid
from contextlib import redirect_stdout
from io import StringIO
from pathlib import Path

from hiveos import config as config_module
from hiveos.intelligence import tracing as tracing_module
from hiveos_trace.cli import main as trace_main


class HiveosTraceNamespaceTests(unittest.TestCase):
    def setUp(self):
        self._original_trace_db_async = tracing_module.TRACE_DB_ASYNC
        self._original_trace_sampling_enabled = tracing_module.TRACE_SAMPLING_ENABLED
        self._original_trace_log_path = tracing_module.TRACE_LOG_PATH
        self._original_trace_home = os.environ.get("HIVE_TRACE_HOME")
        self._original_open_on_run = config_module.TRACE_OPEN_ON_RUN

        self._trace_log_path = str(Path(tempfile.gettempdir()) / f"hive-ns-{uuid.uuid4().hex}.log")
        self._trace_home = str(Path(tempfile.gettempdir()) / f"hive-ns-home-{uuid.uuid4().hex}")
        tracing_module.TRACE_LOG_PATH = self._trace_log_path
        tracing_module.TRACE_DB_ASYNC = False
        tracing_module.TRACE_SAMPLING_ENABLED = False
        os.environ["HIVE_TRACE_HOME"] = self._trace_home
        config_module.TRACE_OPEN_ON_RUN = False

    def tearDown(self):
        tracing_module.TRACE_DB_ASYNC = self._original_trace_db_async
        tracing_module.TRACE_SAMPLING_ENABLED = self._original_trace_sampling_enabled
        tracing_module.TRACE_LOG_PATH = self._original_trace_log_path
        config_module.TRACE_OPEN_ON_RUN = self._original_open_on_run
        if self._original_trace_home is None:
            os.environ.pop("HIVE_TRACE_HOME", None)
        else:
            os.environ["HIVE_TRACE_HOME"] = self._original_trace_home
        self._cleanup_trace_files()
        self._cleanup_trace_home()

    def _cleanup_trace_files(self):
        base = Path(self._trace_log_path)
        for path in [base] + list(base.parent.glob(f"{base.name}.*")):
            try:
                if path.exists():
                    path.unlink()
            except Exception:
                pass

    def _cleanup_trace_home(self):
        home = Path(self._trace_home)
        if not home.exists():
            return
        for path in sorted(home.rglob("*"), reverse=True):
            try:
                if path.is_file():
                    path.unlink()
                elif path.is_dir():
                    path.rmdir()
            except Exception:
                pass

    def test_namespace_passthrough_runs_and_lists(self):
        run_buf = StringIO()
        with redirect_stdout(run_buf):
            code = trace_main(["trace", "run", "--no-open", "--", "python", "-c", "print('ns-pass')"])
        self.assertEqual(0, code)
        out = run_buf.getvalue()
        self.assertIn("run_id=observe-run:", out)

        ls_buf = StringIO()
        with redirect_stdout(ls_buf):
            ls_code = trace_main(["trace", "ls", "--limit", "5"])
        self.assertEqual(0, ls_code)
        self.assertIn("observe-run:", ls_buf.getvalue())


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

