import unittest
from json import JSONDecodeError
from unittest.mock import patch

from pygeai.core.common.exceptions import InvalidAPIResponseException
from pygeai.lab.plugins.tools.clients import ToolPluginClient


class TestToolPluginClient(unittest.TestCase):

    def setUp(self):
        self.project_id = "project-123"
        self.tool_plugin_client = ToolPluginClient(
            api_key="test_key",
            base_url="https://test.url",
            project_id=self.project_id
        )
        self.plugin_id = "plugin-123"
        self.parameters = [{
            "key": "api_key",
            "dataType": "String",
            "description": "API Key",
            "isRequired": True
        }]

    @patch("pygeai.core.services.rest.GEAIApiService.get")
    def test_list_tool_plugins_success(self, mock_get):
        expected_response = {
            "plugins": [
                {"id": "plugin-1", "name": "Plugin1"},
                {"id": "plugin-2", "name": "Plugin2"}
            ]
        }
        mock_response = mock_get.return_value
        mock_response.status_code = 200
        mock_response.json.return_value = expected_response

        result = self.tool_plugin_client.list_plugins(
            count=10,
            access_scope="private",
            allow_drafts=True
        )

        self.assertEqual(result, expected_response)
        mock_get.assert_called_once()

    @patch("pygeai.core.services.rest.GEAIApiService.get")
    def test_list_tool_plugins_json_decode_error(self, mock_get):
        mock_response = mock_get.return_value
        mock_response.status_code = 200
        mock_response.json.side_effect = JSONDecodeError("msg", "doc", 0)

        with self.assertRaises(InvalidAPIResponseException):
            self.tool_plugin_client.list_plugins()

    @patch("pygeai.core.services.rest.GEAIApiService.get")
    def test_get_tool_plugin_success(self, mock_get):
        expected_response = {
            "id": self.plugin_id,
            "name": "TestPlugin",
            "revision": 1
        }
        mock_response = mock_get.return_value
        mock_response.status_code = 200
        mock_response.json.return_value = expected_response

        result = self.tool_plugin_client.get_plugin(
            plugin_id_or_name=self.plugin_id,
            revision=1,
            version=0
        )

        self.assertEqual(result, expected_response)
        mock_get.assert_called_once()

    @patch("pygeai.core.services.rest.GEAIApiService.get")
    def test_get_tool_plugin_json_decode_error(self, mock_get):
        mock_response = mock_get.return_value
        mock_response.status_code = 200
        mock_response.json.side_effect = JSONDecodeError("msg", "doc", 0)

        with self.assertRaises(InvalidAPIResponseException):
            self.tool_plugin_client.get_plugin(plugin_id_or_name=self.plugin_id)

    @patch("pygeai.core.services.rest.GEAIApiService.get")
    def test_get_tool_plugin_config_success(self, mock_get):
        expected_response = {
            "parameters": self.parameters
        }
        mock_response = mock_get.return_value
        mock_response.status_code = 200
        mock_response.json.return_value = expected_response

        result = self.tool_plugin_client.get_config(
            plugin_id_or_name=self.plugin_id
        )

        self.assertEqual(result, expected_response)
        mock_get.assert_called_once()

    @patch("pygeai.core.services.rest.GEAIApiService.get")
    def test_get_tool_plugin_config_json_decode_error(self, mock_get):
        mock_response = mock_get.return_value
        mock_response.status_code = 200
        mock_response.json.side_effect = JSONDecodeError("msg", "doc", 0)

        with self.assertRaises(InvalidAPIResponseException):
            self.tool_plugin_client.get_config(plugin_id_or_name=self.plugin_id)

    @patch("pygeai.core.services.rest.GEAIApiService.post")
    def test_set_tool_plugin_config_success(self, mock_post):
        expected_response = {"message": "Configuration set successfully"}
        mock_response = mock_post.return_value
        mock_response.status_code = 200
        mock_response.json.return_value = expected_response

        result = self.tool_plugin_client.set_config(
            plugin_id_or_name=self.plugin_id,
            parameters=self.parameters
        )

        self.assertEqual(result, expected_response)
        mock_post.assert_called_once()

    @patch("pygeai.core.services.rest.GEAIApiService.post")
    def test_set_tool_plugin_config_json_decode_error(self, mock_post):
        mock_response = mock_post.return_value
        mock_response.status_code = 200
        mock_response.json.side_effect = JSONDecodeError("msg", "doc", 0)

        with self.assertRaises(InvalidAPIResponseException):
            self.tool_plugin_client.set_config(
                plugin_id_or_name=self.plugin_id,
                parameters=self.parameters
            )


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