#!/usr/bin/env python3
# /// script
# requires-python = ">=3.12"
# dependencies = []
# ///
"""Map CloudFormation resources to their tagging APIs.

Chain: resource -> cfn service -> botocore service(s) -> tagging operations

Prefers Resource Groups Tagging API when resource is supported.
"""

import json

from mapping_services import CLOUDFORMATION_TO_BOTOCORE

# Resource Groups Tagging API operations
RESOURCE_GROUPS_TAGGING_OPS = [
    "GetResources",
    "GetTagKeys",
    "GetTagValues",
    "TagResources",
    "UntagResources",
]


def extract_service(resource_type: str) -> str:
    """Extract service name from AWS::<Service>::<Resource> format."""
    parts = resource_type.split("::")
    if len(parts) >= 2:
        return parts[1]
    return ""


def main():
    with open("aws_cloudformation.json") as f:
        resource_types: list[str] = json.load(f)

    with open("tagging_apis.json") as f:
        tagging_apis: dict[str, list[str]] = json.load(f)

    with open("tagging_resource.json") as f:
        rg_tagging_resources: list[str] = json.load(f)

    rg_tagging_set = set(rg_tagging_resources)

    # Build mapping: resource -> tagging info
    result: dict[str, dict] = {}

    for rt in resource_types:
        cfn_service = extract_service(rt)
        botocore_services = CLOUDFORMATION_TO_BOTOCORE.get(cfn_service, [])

        # Check if supported by Resource Groups Tagging API
        uses_rg_tagging = rt in rg_tagging_set

        if uses_rg_tagging:
            # Prefer unified API
            tag_operations = {"resourcegroupstaggingapi": RESOURCE_GROUPS_TAGGING_OPS}
        else:
            # Fall back to service-specific APIs
            tag_operations: dict[str, list[str]] = {}
            for boto_svc in botocore_services:
                ops = tagging_apis.get(boto_svc, [])
                if ops:
                    tag_operations[boto_svc] = ops

        result[rt] = {
            "cfn_service": cfn_service,
            "botocore_services": botocore_services,
            "uses_rg_tagging": uses_rg_tagging,
            "tagging_operations": tag_operations,
        }

    # Stats
    with_rg_tagging = sum(1 for v in result.values() if v["uses_rg_tagging"])
    with_specific = sum(
        1 for v in result.values()
        if not v["uses_rg_tagging"] and v["tagging_operations"]
    )
    without_tagging = sum(
        1 for v in result.values()
        if not v["uses_rg_tagging"] and not v["tagging_operations"]
    )
    no_botocore = sum(1 for v in result.values() if not v["botocore_services"])

    print(f"Total resources: {len(result)}")
    print(f"With RG Tagging API: {with_rg_tagging}")
    print(f"With service-specific API: {with_specific}")
    print(f"Without tagging APIs: {without_tagging}")
    print(f"No botocore mapping: {no_botocore}")

    with open("mapping_resource_tagging.json", "w") as f:
        json.dump(result, f, indent=2, sort_keys=True)

    print("\nSaved mapping_resource_tagging.json")

    # Show some examples
    print("\nExamples:")
    for rt in ["AWS::S3::Bucket", "AWS::Lambda::Function", "AWS::EC2::Instance"]:
        info = result.get(rt, {})
        rg = info.get("uses_rg_tagging", False)
        ops = info.get("tagging_operations", {})
        print(f"  {rt}: {'RG Tagging' if rg else 'service-specific'}")
        for svc, op_list in ops.items():
            print(f"    {svc}: {op_list}")


if __name__ == "__main__":
    main()
