from slurpit.apis.baseapi import BaseAPI
from slurpit.models.rules import TransformRule, AlertRule
from slurpit.utils.utils import handle_response_data, json_to_toon_bytes

class RulesAPI(BaseAPI):
    def __init__(self, base_url, api_key, verify):
        """
        Initialize the RulesAPI with the base URL of the API and an API key for authentication.
        
        Args:
            base_url (str): The root URL for the API endpoints.
            api_key (str): The API key used for authenticating requests.
            verify (bool): Verify HTTPS Certificates.
        """
        formatted_url = "{}/api".format(base_url if base_url[-1] != "/" else base_url[:-1])
        self.base_url = formatted_url
        super().__init__(api_key, verify)

    async def get_alert_rules(self, offset: int = 0, limit: int = 1000, export_csv: bool = False, export_df: bool = False, format: str = "json"):
        """
        List alert rules.

        Args:
            offset (int): The starting index of the records to fetch.
            limit (int): The maximum number of records to return in one call.
            format (str): The desired output format ("json", "csv", "dataframe", "toon"). Default is "json".

        Returns:
            list[AlertRule] | bytes | pd.DataFrame: A list of alert rules, CSV/TOON data as bytes,
                                            or a pandas DataFrame depending on the export format.
        """
        url = f"{self.base_url}/rules/alertrules"
        response = await self._pager(url, offset=offset, limit=limit)
        return handle_response_data(response, AlertRule, export_csv, export_df, format=format)

    async def add_alert_rule(self, rule_data: dict, format: str = "json"):
        """
        Create alert rule.

        Args:
            rule_data (dict): A dictionary containing the alert rule configuration.
            format (str): The desired output format ("json", "toon"). Default is "json".

        Returns:
            AlertRule | bytes: Response from the API or TOON bytes if successful.
        """
        url = f"{self.base_url}/rules/alertrules"
        response = await self.post(url, rule_data)
        if response:
            if format == "toon":
                return json_to_toon_bytes(response.json())
            return AlertRule(**response.json())

    async def get_alert_rule(self, rule_id: int, format: str = "json"):
        """
        Retrieve a single alert rule.

        Args:
            rule_id (int): Alert rule ID.
            format (str): The desired output format ("json", "toon"). Default is "json".

        Returns:
            AlertRule | bytes: Response from the API or TOON bytes if successful.
        """
        url = f"{self.base_url}/rules/alertrules/{rule_id}"
        response = await self.get(url)
        if response:
            if format == "toon":
                return json_to_toon_bytes(response.json())
            return AlertRule(**response.json())

    async def update_alert_rule(self, rule_id: int, rule_data: dict, format: str = "json"):
        """
        Update alert rule.

        Args:
            rule_id (int): Alert rule ID.
            rule_data (dict): A dictionary containing the updated alert rule configuration.
            format (str): The desired output format ("json", "toon"). Default is "json".

        Returns:
            AlertRule | bytes: Response from the API or TOON bytes if successful.
        """
        url = f"{self.base_url}/rules/alertrules/{rule_id}"
        response = await self.put(url, rule_data)
        if response:
            if format == "toon":
                return json_to_toon_bytes(response.json())
            return AlertRule(**response.json())

    async def delete_alert_rule(self, rule_id: int, format: str = "json"):
        """
        Delete alert rule.

        Args:
            rule_id (int): Alert rule ID.
            format (str): The desired output format ("json", "toon"). Default is "json".

        Returns:
            AlertRule | bytes: Response from the API or TOON bytes if successful.
        """
        url = f"{self.base_url}/rules/alertrules/{rule_id}"
        response = await self.delete(url)
        if response:
            if format == "toon":
                return json_to_toon_bytes(response.json())
            return AlertRule(**response.json())

    async def test_alert_rule(self, rule_data: dict, format: str = "json"):
        """
        Test alert rule.

        Args:
            rule_data (dict): A dictionary containing the alert rule data to test.
            format (str): The desired output format ("json", "toon"). Default is "json".

        Returns:
            dict | bytes: Result of the test or TOON bytes if successful.
        """
        url = f"{self.base_url}/rules/alertrules/test"
        response = await self.post(url, rule_data)
        if response:
            if format == "toon":
                return json_to_toon_bytes(response.json())
            return response.json()

    async def get_transform_rules(self, offset: int = 0, limit: int = 1000, export_csv: bool = False, export_df: bool = False, format: str = "json"):
        """
        List transform rules.

        Args:
            offset (int): The starting index of the records to fetch.
            limit (int): The maximum number of records to return in one call.
            format (str): The desired output format ("json", "csv", "dataframe", "toon"). Default is "json".

        Returns:
            list[TransformRule] | bytes | pd.DataFrame: A list of transform rules, CSV/TOON data as bytes,
                                            or a pandas DataFrame depending on the export format.
        """
        url = f"{self.base_url}/rules/transformrules"
        response = await self._pager(url, offset=offset, limit=limit)
        return handle_response_data(response, TransformRule, export_csv, export_df, format=format)

    async def add_transform_rule(self, rule_data: dict, format: str = "json"):
        """
        Create transform rule.

        Args:
            rule_data (dict): A dictionary containing the transform rule configuration.
            format (str): The desired output format ("json", "toon"). Default is "json".

        Returns:
            TransformRule | bytes: Response from the API or TOON bytes if successful.
        """
        url = f"{self.base_url}/rules/transformrules"
        response = await self.post(url, rule_data)
        if response:
            if format == "toon":
                return json_to_toon_bytes(response.json())
            return TransformRule(**response.json())

    async def get_transform_rule(self, rule_id: int, format: str = "json"):
        """
        Retrieve a single transform rule.

        Args:
            rule_id (int): Transform rule ID.
            format (str): The desired output format ("json", "toon"). Default is "json".

        Returns:
            TransformRule | bytes: Response from the API or TOON bytes if successful.
        """
        url = f"{self.base_url}/rules/transformrules/{rule_id}"
        response = await self.get(url)
        if response:
            if format == "toon":
                return json_to_toon_bytes(response.json())
            return TransformRule(**response.json())

    async def update_transform_rule(self, rule_id: int, rule_data: dict, format: str = "json"):
        """
        Update transform rule.

        Args:
            rule_id (int): Transform rule ID.
            rule_data (dict): A dictionary containing the updated transform rule configuration.
            format (str): The desired output format ("json", "toon"). Default is "json".

        Returns:
            TransformRule | bytes: Response from the API or TOON bytes if successful.
        """
        url = f"{self.base_url}/rules/transformrules/{rule_id}"
        response = await self.put(url, rule_data)
        if response:
            if format == "toon":
                return json_to_toon_bytes(response.json())
            return TransformRule(**response.json())

    async def delete_transform_rule(self, rule_id: int, format: str = "json"):
        """
        Delete transform rule.

        Args:
            rule_id (int): Transform rule ID.
            format (str): The desired output format ("json", "toon"). Default is "json".

        Returns:
            TransformRule | bytes: Response from the API or TOON bytes if successful.
        """
        url = f"{self.base_url}/rules/transformrules/{rule_id}"
        response = await self.delete(url)
        if response:
            if format == "toon":
                return json_to_toon_bytes(response.json())
            return TransformRule(**response.json())

    async def test_transform_rule(self, rule_data: dict, format: str = "json"):
        """
        Test transform rule.

        Args:
            rule_data (dict): A dictionary containing the transform rule data to test.
            format (str): The desired output format ("json", "toon"). Default is "json".

        Returns:
            dict | bytes: Result of the test or TOON bytes if successful.
        """
        url = f"{self.base_url}/rules/transformrules/test"
        response = await self.post(url, rule_data)
        if response:
            if format == "toon":
                return json_to_toon_bytes(response.json())
            return response.json()
