"""
Checks the last hour of AWS Billing Data from S3 buckets, and sends an alert if
any servers have exceeded the specified threshold.

Note: This Action assumes that you have one or more configured Alert Channels
    that can be used for notifying the appropraite users. These channels must
    be listed in ALERT_CHANNEL_NAMES below.

Version:
    Requires >= v9.0.1
"""

import json
from typing import List

from alerts.methods import alert
from resourcehandlers.aws.models import AWSHandler

AWS_COST_THRESHOLD = 100
ALERT_CHANNEL_NAMES: List[str] = []


class AWSCostAlert:
    def __init__(self):
        self.over_threshold = []

    def __call__(self):
        """
        Retrieve cost data for all AWS Resource Handlers and alert if any
        servers exceed the specified threshold.
        """
        aws_instances = AWSHandler.objects.all()
        for aws in aws_instances:
            last_hours_data = aws.get_last_hour_billing_data()
            self.__check_threshold(last_hours_data)

        _ = self.__alert_over_threshold()

    def __check_threshold(self, data_list):
        """
        Parse server information for instances that exceed the threshold.

        Args:
            data_list (List[Tuple[str, float]]): [(server_id, cost)]
        """
        _exceed_threshold_list = []
        for server_id, cost in data_list:
            if cost >= AWS_COST_THRESHOLD:
                _exceed_threshold_list.append((server_id, cost))
        self.over_threshold.extend(_exceed_threshold_list)
        return

    def __alert_over_threshold(self):
        """
        Send alert for all server instances that exceed the threshold.

        Returns:
            None
        """
        instance_dict = dict(self.over_threshold)
        instance_json = json.dumps(instance_dict, indent=4)
        message = (
            f"The following servers exceeded the AWS cost threshold of {AWS_COST_THRESHOLD}:"
            f"{instance_json}"
        )
        for channel_name in ALERT_CHANNEL_NAMES:
            alert(channel_name, message)

        return None


def run(*args, **kwargs):
    cost_alert = AWSCostAlert()
    cost_alert()

    return "SUCCESS", "", ""

Add AWS Hourly Spending Anomaly Detection
Add AWS Hourly Spending Anomaly Detection

New plugin checks hourly spending data for all AWS instances and sends
an alert if the cost threshold has been exceeded.

[DEV-13347]
