from typing import List

from pygeai.lab.models import ToolPlugin, ToolPluginList, ToolParameter


class ToolPluginMapper:
    """
    Mapper class for converting API responses to ToolPlugin models.
    
    This class provides methods to map raw API response dictionaries to structured
    ToolPlugin and ToolParameter objects.
    """

    @classmethod
    def map_to_tool_plugin(cls, data: dict) -> ToolPlugin:
        """
        Maps a dictionary to a ToolPlugin object using Pydantic model validation.

        :param data: dict - The raw data from API response.
            Expected fields include id, name, and potentially other plugin metadata.
        :return: ToolPlugin - A ToolPlugin object representing the plugin configuration.
        """
        plugin_data = data.get("plugin", data)
        return ToolPlugin.model_validate(plugin_data)

    @classmethod
    def map_to_tool_plugin_list(cls, data: dict) -> ToolPluginList:
        """
        Maps an API response dictionary to a `ToolPluginList` object.

        This method extracts plugins from the given data, converts them into a list of `ToolPlugin` objects,
        and returns a `ToolPluginList` containing the list.

        :param data: dict - The dictionary containing plugin response data, expected to have a 'plugins' key or be a list.
        :return: ToolPluginList - A structured response containing a list of tool-plugins.
        """
        plugin_list = []
        plugins = data if isinstance(data, list) else data.get("plugins", [])
        if plugins and any(plugins):
            for plugin_data in plugins:
                plugin = cls.map_to_tool_plugin(plugin_data)
                plugin_list.append(plugin)

        return ToolPluginList(plugins=plugin_list)

    @classmethod
    def map_to_config(cls, data: dict) -> List[ToolParameter]:
        """
        Maps an API config response dictionary to a list of ToolParameter objects.

        This method handles the plugin configuration response which contains parameters
        that can be inherited by tools belonging to the plugin.

        :param data: dict - The dictionary containing config response data, expected to have a 'parameters' key or be a list.
        :return: List[ToolParameter] - A list of ToolParameter objects with inheritance metadata.
        
        Example input:
        {
            "parameters": [
                {
                    "key": "clientId",
                    "dataType": "String",
                    "isRequired": true,
                    "type": "config",
                    "value": "mySecret",
                    "fromSecret": true
                }
            ]
        }
        """
        params_data = data if isinstance(data, list) else data.get("parameters", [])
        return cls._map_parameters(params_data)

    @classmethod
    def _map_parameters(cls, params_data: List[dict]) -> List[ToolParameter]:
        """
        Maps a list of parameter dictionaries to a list of ToolParameter objects.

        This method uses Pydantic's model_validate to handle all fields including
        the new inheritance fields (isInherited, valueFrom).

        :param params_data: List[dict] - List of raw parameter data.
        :return: List[ToolParameter] - List of mapped ToolParameter objects.
        """
        return [
            ToolParameter.model_validate(param)
            for param in params_data
        ]
