from tfcost.pricing.resource_pricing_map import RESOURCE_PRICING_MAP
from tfcost.pricing.service_detector import detect_service
from tfcost.pricing.aws_pricing import get_instance_price, get_storage_price

HOURS_PER_MONTH = 730.5


def calculate_resource_cost(resource, region):

    rtype = resource["type"]
    config = resource["config"]

    rule = RESOURCE_PRICING_MAP.get(rtype)

    # -----------------------------
    # Unsupported resource
    # -----------------------------
    if not rule:

        service = detect_service(rtype)

        return {
            "service": service,
            "cost": 0
        }

    service = rule["service"]
    model = rule["pricing_model"]

    # -----------------------------
    # INSTANCE PRICING
    # EC2 / RDS / ElastiCache
    # -----------------------------
    if model == "instance_hour":

        instance_type = config.get(rule["lookup"])

        if not instance_type:
            return {"service": service, "cost": 0}

        price = get_instance_price(instance_type, region)

        return {
            "service": service,
            "cost": price * HOURS_PER_MONTH
        }

    # -----------------------------
    # STORAGE PRICING
    # EBS / EFS
    # -----------------------------
    if model == "storage_gb_month":

        size = config.get(rule.get("size"), rule.get("default_size", 0))

        volume_type = config.get(rule.get("lookup"), "gp3")

        price = get_storage_price(volume_type, region)

        return {
            "service": service,
            "cost": price * size
        }

    # -----------------------------
    # FIXED HOURLY COST
    # NAT Gateway / EKS Control Plane
    # -----------------------------
    if model == "hourly_fixed":

        price = rule["price"]

        return {
            "service": service,
            "cost": price * HOURS_PER_MONTH
        }

    # -----------------------------
    # EKS NODE GROUP PRICING
    # Worker nodes are EC2 instances
    # -----------------------------
    if model == "eks_node_group":

        instance_types = config.get(rule["lookup"], [])

        if not instance_types:
            return {"service": service, "cost": 0}

        instance_type = instance_types[0]

        node_count = config.get(rule.get("count"), 1)

        if not node_count:
            node_count = 1

        price = get_instance_price(instance_type, region)

        return {
            "service": service,
            "cost": price * HOURS_PER_MONTH * node_count
        }

    # -----------------------------
    # S3 ESTIMATION
    # -----------------------------
    if model == "bucket_storage":

        storage = rule.get("default_size", 10)

        price = rule.get("price_per_gb", 0.023)

        return {
            "service": service,
            "cost": storage * price
        }

    # -----------------------------
    # FALLBACK
    # -----------------------------
    return {
        "service": service,
        "cost": 0
    }