from __future__ import annotations

import asyncio
import tempfile
import unittest
from pathlib import Path

from openclaw_lite.config import ConfigManager, init_project_layout
from openclaw_lite.core.shell import ShellExecutor, ShellSafetyError


class ConfigManagerTest(unittest.TestCase):
    def test_creates_default_config_and_layout(self) -> None:
        with tempfile.TemporaryDirectory() as tmp:
            config_path = Path(tmp) / "config.yaml"
            manager = ConfigManager(config_path)
            init_project_layout(manager)
            self.assertTrue(config_path.exists())
            self.assertTrue(Path(manager.get("workspace_dir")).exists())
            self.assertTrue(Path(manager.get("workspace_dir")) .joinpath("skills").exists())


class ShellExecutorTest(unittest.TestCase):
    def test_safe_mode_rejects_metacharacters(self) -> None:
        with tempfile.TemporaryDirectory() as tmp:
            config = {
                "project_root": tmp,
                "workspace_dir": str(Path(tmp) / "workspace"),
                "data_dir": str(Path(tmp) / "data"),
                "logs_dir": str(Path(tmp) / "logs"),
                "backups_dir": str(Path(tmp) / "backups"),
                "shell": {
                    "timeout_seconds": 5,
                    "max_output_chars": 4000,
                    "safe_allowed_commands": ["echo", "pwd"],
                },
            }
            Path(config["workspace_dir"]).mkdir(parents=True, exist_ok=True)
            executor = ShellExecutor(config)
            with self.assertRaises(ShellSafetyError):
                asyncio.run(executor.run("echo ok && pwd", mode="safe"))

    def test_safe_mode_allows_basic_echo(self) -> None:
        with tempfile.TemporaryDirectory() as tmp:
            config = {
                "project_root": tmp,
                "workspace_dir": str(Path(tmp) / "workspace"),
                "data_dir": str(Path(tmp) / "data"),
                "logs_dir": str(Path(tmp) / "logs"),
                "backups_dir": str(Path(tmp) / "backups"),
                "shell": {
                    "timeout_seconds": 5,
                    "max_output_chars": 4000,
                    "safe_allowed_commands": ["echo", "pwd"],
                },
            }
            Path(config["workspace_dir"]).mkdir(parents=True, exist_ok=True)
            executor = ShellExecutor(config)
            result = asyncio.run(executor.run("echo hello", mode="safe"))
            self.assertEqual(result.exit_code, 0)
            self.assertIn("hello", result.stdout)


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