#!/usr/bin/env python3
# /// script
# requires-python = ">=3.12"
# dependencies = ["botocore"]
# ///
"""Helper to find next unmapped CloudFormation service."""

import json
import re
from difflib import SequenceMatcher

import botocore.session

from mapping_services import CLOUDFORMATION_TO_BOTOCORE


def get_boto_metadata() -> dict[str, str]:
    """Get serviceId for each botocore service."""
    session = botocore.session.get_session()
    result = {}
    for name in session.get_available_services():
        data = session.get_service_data(name)
        result[name] = data.get("metadata", {}).get("serviceId", "")
    return result


def normalize(s: str) -> str:
    """Normalize for comparison: lowercase, no hyphens/spaces."""
    return re.sub(r"[-\s]", "", s.lower())


def find_matches(cf_name: str, boto_services: list[str], boto_meta: dict[str, str]) -> list[str]:
    """Find matching botocore services using multiple strategies."""
    cf_norm = normalize(cf_name)
    scores: dict[str, float] = {}

    for boto in boto_services:
        boto_norm = normalize(boto)
        service_id_norm = normalize(boto_meta.get(boto, ""))

        # Exact match on normalized
        if cf_norm == boto_norm or cf_norm == service_id_norm:
            scores[boto] = 1.0
            continue

        # Substring match
        if cf_norm in boto_norm or boto_norm in cf_norm:
            scores[boto] = 0.8
            continue

        if cf_norm in service_id_norm or service_id_norm in cf_norm:
            scores[boto] = 0.8
            continue

        # Fuzzy match
        ratio = max(
            SequenceMatcher(None, cf_norm, boto_norm).ratio(),
            SequenceMatcher(None, cf_norm, service_id_norm).ratio(),
        )
        if ratio > 0.5:
            scores[boto] = ratio

    return sorted(scores.keys(), key=lambda x: -scores[x])[:5]


def main():
    with open("aws_cloudformation_services.json") as f:
        cf_services = json.load(f)

    with open("aws_services.json") as f:
        boto_services = json.load(f)

    boto_meta = get_boto_metadata()
    mapped = set(CLOUDFORMATION_TO_BOTOCORE.keys())

    for cf in cf_services:
        if cf not in mapped:
            matches = find_matches(cf, boto_services, boto_meta)
            print(f"Next: {cf}")
            print(f"Suggestions: {matches}")
            print(f"Progress: {len(mapped)}/263")
            break
    else:
        print("All mapped!")


if __name__ == "__main__":
    main()
