"""Tests for the connection test CLI command."""

import argparse
import unittest
from types import SimpleNamespace
from unittest.mock import MagicMock, patch

from data_exchange_agent.cli.connection_test_command import run_connection_test


class TestRunConnectionTest(unittest.TestCase):
    """Tests for run_connection_test."""

    @patch("data_exchange_agent.cli.connection_test_command.print_test_results")
    @patch("data_exchange_agent.cli.connection_test_command.ConnectionTester")
    @patch("data_exchange_agent.cli.connection_test_command.ConfigManager")
    @patch("data_exchange_agent.cli.connection_test_command.os.path.isfile", return_value=False)
    @patch(
        "data_exchange_agent.cli.connection_test_command.get_configuration_file_path",
        return_value="/default/config.toml",
    )
    def test_config_missing_uses_default_path_message(
        self,
        _mock_get_path,
        _mock_isfile,
        _mock_config_mgr,
        _mock_tester,
        _mock_print_results,
    ):
        args = argparse.Namespace()
        with patch("builtins.print") as mock_print:
            code = run_connection_test(args)
        self.assertEqual(code, 1)
        joined = " ".join(str(c.args[0]) for c in mock_print.call_args_list if c.args)
        self.assertIn("Searched:", joined)

    @patch("data_exchange_agent.cli.connection_test_command.print_test_results")
    @patch("data_exchange_agent.cli.connection_test_command.ConnectionTester")
    @patch("data_exchange_agent.cli.connection_test_command.ConfigManager")
    @patch("data_exchange_agent.cli.connection_test_command.os.path.isfile", return_value=True)
    def test_load_toml_config_error_uses_cause(self, _mock_isfile, mock_config_mgr_cls, _mock_tester, _mock_print_results):
        root = ValueError("root problem")
        wrapper = RuntimeError("wrapper")
        wrapper.__cause__ = root
        mock_config = MagicMock()
        mock_config.load_toml_config.side_effect = wrapper
        mock_config_mgr_cls.return_value = mock_config
        args = argparse.Namespace(config="/ok.toml")
        with patch("builtins.print") as mock_print:
            code = run_connection_test(args)
        self.assertEqual(code, 1)
        config_error_lines = [c.args[0] for c in mock_print.call_args_list if c.args and "Config error" in str(c.args[0])]
        self.assertTrue(config_error_lines)
        self.assertIn("root problem", config_error_lines[0])

    @patch("data_exchange_agent.cli.connection_test_command.print_test_results")
    @patch("data_exchange_agent.cli.connection_test_command.ConnectionTester")
    @patch("data_exchange_agent.cli.connection_test_command.ConfigManager")
    @patch("data_exchange_agent.cli.connection_test_command.os.path.isfile", return_value=True)
    def test_load_toml_config_error_no_cause(self, _mock_isfile, mock_config_mgr_cls, _mock_tester_cls, _mock_print_results):
        mock_config = MagicMock()
        mock_config.load_toml_config.side_effect = OSError("direct failure")
        mock_config_mgr_cls.return_value = mock_config
        args = argparse.Namespace(config="/ok.toml")
        with patch("builtins.print") as mock_print:
            code = run_connection_test(args)
        self.assertEqual(code, 1)
        self.assertTrue(any("direct failure" in str(c.args[0]) for c in mock_print.call_args_list if c.args))

    @patch("data_exchange_agent.cli.connection_test_command.print_test_results")
    @patch("data_exchange_agent.cli.connection_test_command.ConnectionTester")
    @patch("data_exchange_agent.cli.connection_test_command.ConfigManager")
    @patch("data_exchange_agent.cli.connection_test_command.os.path.isfile", return_value=True)
    def test_all_connections_ok(self, _mock_isfile, mock_config_mgr_cls, mock_tester_cls, mock_print_results):
        mock_config = MagicMock()
        mock_config_mgr_cls.return_value = mock_config
        ok = SimpleNamespace(is_success=True)
        mock_tester = MagicMock()
        mock_tester.test_source_connections.return_value = [ok]
        mock_tester.test_target_connections.return_value = [ok]
        mock_tester_cls.return_value = mock_tester
        args = argparse.Namespace(config="/ok.toml")
        with patch("builtins.print"):
            code = run_connection_test(args)
        self.assertEqual(code, 0)
        self.assertEqual(mock_print_results.call_count, 2)

    @patch("data_exchange_agent.cli.connection_test_command.print_test_results")
    @patch("data_exchange_agent.cli.connection_test_command.ConnectionTester")
    @patch("data_exchange_agent.cli.connection_test_command.ConfigManager")
    @patch("data_exchange_agent.cli.connection_test_command.os.path.isfile", return_value=True)
    def test_some_connection_fails(self, _mock_isfile, mock_config_mgr_cls, mock_tester_cls, _mock_print_results):
        mock_config = MagicMock()
        mock_config_mgr_cls.return_value = mock_config
        ok = SimpleNamespace(is_success=True)
        bad = SimpleNamespace(is_success=False)
        mock_tester = MagicMock()
        mock_tester.test_source_connections.return_value = [ok]
        mock_tester.test_target_connections.return_value = [bad]
        mock_tester_cls.return_value = mock_tester
        args = argparse.Namespace(config="/ok.toml")
        with patch("builtins.print"):
            code = run_connection_test(args)
        self.assertEqual(code, 1)

    @patch("data_exchange_agent.cli.connection_test_command.print_test_results")
    @patch("data_exchange_agent.cli.connection_test_command.ConnectionTester")
    @patch("data_exchange_agent.cli.connection_test_command.ConfigManager")
    @patch("data_exchange_agent.cli.connection_test_command.os.path.isfile", return_value=True)
    def test_no_source_no_target_still_success_exit(self, _mock_isfile, mock_config_mgr_cls, mock_tester_cls, mock_print_results):
        mock_config = MagicMock()
        mock_config_mgr_cls.return_value = mock_config
        mock_tester = MagicMock()
        mock_tester.test_source_connections.return_value = []
        mock_tester.test_target_connections.return_value = []
        mock_tester_cls.return_value = mock_tester
        args = argparse.Namespace(config="/ok.toml")
        with patch("builtins.print"):
            code = run_connection_test(args)
        self.assertEqual(code, 0)
        mock_print_results.assert_not_called()


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