"""Launch Configuration usage report."""

from dataclasses import dataclass, field
from datetime import datetime

import boto3
from rich.console import Console

console = Console()


@dataclass
class Reference:
    """A reference to a Launch Configuration from another AWS resource."""

    type: str  # ASG
    name: str  # human-readable identifier


@dataclass
class LaunchConfigInfo:
    """Basic Launch Configuration info from AWS."""

    name: str
    created: datetime
    ami_id: str


@dataclass
class LaunchConfigReport:
    """Launch Configuration with its references."""

    name: str
    created: datetime
    ami_id: str
    references: list[Reference] = field(default_factory=list)

    @property
    def is_orphaned(self) -> bool:
        return len(self.references) == 0

    def to_dict(self) -> dict:
        return {
            "name": self.name,
            "created": self.created.isoformat(),
            "ami_id": self.ami_id,
            "references": [{"type": r.type, "name": r.name} for r in self.references],
            "is_orphaned": self.is_orphaned,
        }


def get_launch_configs(session: boto3.Session) -> dict[str, LaunchConfigInfo]:
    """Fetch all Launch Configurations. Returns {lc_name: LaunchConfigInfo}."""
    autoscaling = session.client("autoscaling")
    paginator = autoscaling.get_paginator("describe_launch_configurations")

    configs = {}
    for page in paginator.paginate():
        for lc in page["LaunchConfigurations"]:
            configs[lc["LaunchConfigurationName"]] = LaunchConfigInfo(
                name=lc["LaunchConfigurationName"],
                created=lc["CreatedTime"],
                ami_id=lc.get("ImageId", ""),
            )

    console.print(f"Found {len(configs)} launch configurations")
    return configs


def get_asg_references(session: boto3.Session) -> dict[str, list[Reference]]:
    """Get Launch Configuration references from Auto Scaling Groups."""
    autoscaling = session.client("autoscaling")
    paginator = autoscaling.get_paginator("describe_auto_scaling_groups")

    refs: dict[str, list[Reference]] = {}
    for page in paginator.paginate():
        for asg in page["AutoScalingGroups"]:
            lc_name = asg.get("LaunchConfigurationName")
            if lc_name:
                refs.setdefault(lc_name, []).append(
                    Reference(type="ASG", name=asg["AutoScalingGroupName"])
                )

    console.print(f"Found {sum(len(v) for v in refs.values())} ASG references")
    return refs


def build_report(
    session: boto3.Session | None = None,
) -> list[LaunchConfigReport]:
    """Build Launch Configuration usage report."""
    if session is None:
        session = boto3.Session()

    # Fetch all data
    configs = get_launch_configs(session)
    asg_refs = get_asg_references(session)

    # Build report
    report = []
    for lc_name, lc_info in configs.items():
        report.append(
            LaunchConfigReport(
                name=lc_info.name,
                created=lc_info.created,
                ami_id=lc_info.ami_id,
                references=asg_refs.get(lc_name, []),
            )
        )

    return report
