import os
import sys
import tempfile
import unittest
from pathlib import Path
from unittest import mock

from core import paths
from core.service_wrapper import RelayServiceWrapper


class TestPackagingPaths(unittest.TestCase):
    def test_source_paths_remain_repository_relative(self):
        self.assertEqual(Path(__file__).resolve().parent.parent, paths.application_root())
        self.assertEqual(paths.application_root() / "config" / "process_monitor_config.json", paths.config_path())

    def test_frozen_paths_separate_resources_from_writable_state(self):
        with tempfile.TemporaryDirectory() as tmp:
            root = Path(tmp); exe = root / "ProcessMonitor.exe"; local_data = root / "LocalAppData"
            with mock.patch.object(sys, "frozen", True, create=True), mock.patch.object(sys, "executable", str(exe)), \
                    mock.patch.dict(os.environ, {"LOCALAPPDATA": str(local_data)}, clear=False):
                self.assertEqual(root, paths.application_root())
                self.assertEqual(root / "config" / "process_monitor_config.json", paths.config_path())
                self.assertEqual(local_data / "ProcessMonitor", paths.runtime_root())

    def test_environment_overrides_support_portable_and_test_deployments(self):
        with tempfile.TemporaryDirectory() as tmp, mock.patch.dict(os.environ, {
                "PROCESSMONITOR_APP_ROOT": str(Path(tmp) / "app"),
                "PROCESSMONITOR_DATA_ROOT": str(Path(tmp) / "state"),
                "PROCESSMONITOR_CONFIG": str(Path(tmp) / "policy.json")}, clear=False):
            self.assertEqual((Path(tmp) / "app").resolve(), paths.application_root())
            self.assertEqual((Path(tmp) / "state").resolve(), paths.runtime_root())
            self.assertEqual((Path(tmp) / "policy.json").resolve(), paths.config_path())

    def test_frozen_gui_targets_sibling_relay_executable(self):
        with tempfile.TemporaryDirectory() as tmp:
            root = Path(tmp); gui = root / "ProcessMonitor.exe"; relay = root / "ProcessMonitorRelay.exe"
            relay.touch()
            with mock.patch("core.service_wrapper.is_frozen", return_value=True), \
                    mock.patch("core.service_wrapper.application_root", return_value=root), \
                    mock.patch("core.service_wrapper.relay_executable", return_value=relay), \
                    mock.patch.object(sys, "executable", str(gui)):
                wrapper = RelayServiceWrapper.__new__(RelayServiceWrapper)
                wrapper.config_path = root / "config.json"
                wrapper.runtime_dir = root / "runtime"
                command = wrapper._worker_command()
            self.assertEqual(str(relay), command[0])
            self.assertNotIn("-m", command)


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