from __future__ import annotations

import tempfile
import unittest
from pathlib import Path

from src.agent_tools import build_tool_context, default_tool_registry, execute_tool
from src.agent_types import AgentRuntimeConfig
from src.remote_runtime import (
    RemoteRuntime,
    run_deep_link_mode,
    run_direct_connect_mode,
    run_remote_mode,
    run_ssh_mode,
    run_teleport_mode,
)


class RemoteRuntimeTests(unittest.TestCase):
    def test_remote_runtime_discovers_profiles_and_persists_connection(self) -> None:
        with tempfile.TemporaryDirectory() as tmp_dir:
            workspace = Path(tmp_dir)
            (workspace / '.claw-remote.json').write_text(
                (
                    '{"profiles":['
                    '{"name":"staging","mode":"ssh","target":"dev@staging","workspaceCwd":"/srv/app"},'
                    '{"name":"preview","mode":"deep-link","target":"preview://session"}'
                    ']}'
                ),
                encoding='utf-8',
            )
            runtime = RemoteRuntime.from_workspace(workspace)
            report = runtime.connect('staging')
            restored = RemoteRuntime.from_workspace(workspace)

        self.assertEqual(len(runtime.profiles), 2)
        self.assertTrue(report.connected)
        self.assertEqual(report.profile_name, 'staging')
        self.assertIsNotNone(restored.active_connection)
        self.assertEqual(restored.active_connection.profile_name, 'staging')
        self.assertIn('Configured remote profiles: 2', restored.render_summary())

    def test_remote_runtime_disconnect_clears_active_connection(self) -> None:
        with tempfile.TemporaryDirectory() as tmp_dir:
            workspace = Path(tmp_dir)
            (workspace / '.claw-remote.json').write_text(
                '{"profiles":[{"name":"staging","mode":"ssh","target":"dev@staging"}]}',
                encoding='utf-8',
            )
            runtime = RemoteRuntime.from_workspace(workspace)
            runtime.connect('staging')
            report = runtime.disconnect()

        self.assertFalse(report.connected)
        self.assertIn('Disconnected ssh target dev@staging', report.detail)

    def test_remote_mode_helpers_use_manifest_backed_profiles(self) -> None:
        with tempfile.TemporaryDirectory() as tmp_dir:
            workspace = Path(tmp_dir)
            (workspace / '.claw-remote.json').write_text(
                (
                    '{"profiles":['
                    '{"name":"workspace","mode":"remote","target":"remote://workspace"},'
                    '{"name":"sshbox","mode":"ssh","target":"dev@sshbox"},'
                    '{"name":"tele","mode":"teleport","target":"teleport://workspace"},'
                    '{"name":"direct","mode":"direct-connect","target":"direct://workspace"},'
                    '{"name":"link","mode":"deep-link","target":"deep://workspace"}'
                    ']}'
                ),
                encoding='utf-8',
            )
            remote_report = run_remote_mode('workspace', cwd=workspace)
            ssh_report = run_ssh_mode('sshbox', cwd=workspace)
            teleport_report = run_teleport_mode('tele', cwd=workspace)
            direct_report = run_direct_connect_mode('direct', cwd=workspace)
            deep_link_report = run_deep_link_mode('link', cwd=workspace)

        self.assertEqual(remote_report.profile_name, 'workspace')
        self.assertEqual(ssh_report.mode, 'ssh')
        self.assertEqual(teleport_report.mode, 'teleport')
        self.assertEqual(direct_report.mode, 'direct-connect')
        self.assertEqual(deep_link_report.mode, 'deep-link')

    def test_remote_tools_execute_against_runtime(self) -> None:
        with tempfile.TemporaryDirectory() as tmp_dir:
            workspace = Path(tmp_dir)
            (workspace / '.claw-remote.json').write_text(
                (
                    '{"profiles":[{"name":"staging","mode":"ssh","target":"dev@staging",'
                    '"workspaceCwd":"/srv/app","sessionUrl":"wss://remote/session"}]}'
                ),
                encoding='utf-8',
            )
            runtime = RemoteRuntime.from_workspace(workspace)
            context = build_tool_context(
                AgentRuntimeConfig(cwd=workspace),
                remote_runtime=runtime,
            )
            list_result = execute_tool(
                default_tool_registry(),
                'remote_list_profiles',
                {},
                context,
            )
            connect_result = execute_tool(
                default_tool_registry(),
                'remote_connect',
                {'target': 'staging'},
                context,
            )
            status_result = execute_tool(
                default_tool_registry(),
                'remote_status',
                {},
                context,
            )

        self.assertTrue(list_result.ok)
        self.assertIn('staging', list_result.content)
        self.assertTrue(connect_result.ok)
        self.assertIn('profile=staging', connect_result.content)
        self.assertTrue(status_result.ok)
        self.assertIn('Configured remote profiles: 1', status_result.content)
