"""
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: MIT-0
"""

import regex as re

from cfnlint._typing import RuleMatches
from cfnlint.rules import CloudFormationLintRule, RuleMatch
from cfnlint.template import Template


class PreviousGenerationInstanceType(CloudFormationLintRule):
    id = "I3100"
    shortdesc = "Checks for legacy instance type generations"
    description = "New instance type generations increase performance and decrease cost"
    source_url = "https://aws.amazon.com/ec2/previous-generation/"
    tags = ["resources", "ec2", "rds", "elasticcache", "elasticsearch"]

    def match(self, cfn: Template) -> RuleMatches:
        matches = []
        for resource_type, property_type in [
            ("AWS::AutoScaling::LaunchConfiguration", "InstanceType"),
            ("AWS::EC2::CapacityReservation", "InstanceType"),
            ("AWS::EC2::Host", "InstanceType"),
            ("AWS::EC2::Instance", "InstanceType"),
            ("AWS::RDS::DBInstance", "DBInstanceClass"),
            ("AWS::ElastiCache::CacheCluster", "CacheNodeType"),
            ("AWS::ElastiCache::GlobalReplicationGroup", "CacheNodeType"),
            ("AWS::ElastiCache::ReplicationGroup", "CacheNodeType"),
        ]:
            for resource_name, resource in cfn.get_resources([resource_type]).items():
                if isinstance(
                    resource.get("Properties", {}).get(property_type, ""), str
                ):
                    if self.__is_previous_generation_instance_type(
                        resource.get("Properties", {}).get(property_type, ""),
                    ):
                        matches.append(
                            RuleMatch(
                                [
                                    "Resources",
                                    resource_name,
                                    "Properties",
                                    property_type,
                                ],
                                "Upgrade previous generation instance type: "
                                + resource.get("Properties", {}).get(property_type),
                            )
                        )

        for resource_type, top_level_property_type, property_type in [
            (
                "AWS::EC2::EC2Fleet",
                "FleetLaunchTemplateOverridesRequest",
                "InstanceType",
            ),
            ("AWS::EC2::LaunchTemplate", "LaunchTemplateData", "InstanceType"),
            ("AWS::EC2::SpotFleet", "SpotFleetLaunchSpecification", "InstanceType"),
            ("AWS::OpenSearchService::Domain", "ClusterConfig", "InstanceType"),
            (
                "AWS::Elasticsearch::Domain",
                "ElasticsearchClusterConfig",
                "InstanceType",
            ),
        ]:
            for resource_name, resource in cfn.get_resources([resource_type]).items():
                if isinstance(
                    resource.get("Properties", {})
                    .get(top_level_property_type, {})
                    .get(property_type, ""),
                    str,
                ):
                    if self.__is_previous_generation_instance_type(
                        resource.get("Properties", {})
                        .get(top_level_property_type, {})
                        .get(property_type, ""),
                    ):
                        matches.append(
                            RuleMatch(
                                [
                                    "Resources",
                                    resource_name,
                                    "Properties",
                                    top_level_property_type,
                                    property_type,
                                ],
                                "Upgrade previous generation instance type: "
                                + resource.get("Properties", {})
                                .get(top_level_property_type, {})
                                .get(property_type),
                            )
                        )
        return matches

    def __is_previous_generation_instance_type(self, instance_type):
        return (
            re.search(
                r"(^|\.)([cmr][1-3]|cc2|cg1|cr1|g2|hi1|hs1|i2|t1)($|\.)", instance_type
            )
            is not None
        )
