"""
S3 (Simple Storage Service) cost optimization detectors.

This module contains detectors for:
- S3 lifecycle policy optimization suggestions
- S3 access logging not enabled (blocks confident lifecycle/IT decisions)
- S3 Intelligent-Tiering not configured on buckets
"""

from typing import Any, Dict, List, Optional

from stacksage.pricing import PRICING_S3_IT_MONITORING_PER_1K_OBJECTS


def detect_s3_lifecycle_suggestions(
    s3_buckets: List[Dict[str, Any]],
) -> List[Dict[str, Any]]:
    """
    Suggests S3 lifecycle policies for cost optimization.

    Note: This is a heuristic detector that recommends lifecycle policies without
    analyzing actual bucket size/access patterns (requires additional API calls not
    available in MVP).

    Args:
        s3_buckets: List of S3 bucket dictionaries from scanner
    """
    findings = []
    for b in s3_buckets:
        findings.append(
            {
                "type": "s3_lifecycle_suggestion",
                "resource_type": "s3",
                "id": b.get("Name"),
                "estimated_monthly_savings_usd": 0,
                "estimated_monthly_savings_hint_source": "heuristic",
                "potential_savings": 0,
                "confidence": 0.5,
                "severity": "low",
                "recommended_action": "add-lifecycle",
                "explanation": "No lifecycle information inspected. Consider adding lifecycle rules to transition infrequently accessed objects to cheaper storage.",
                "evidence": {
                    "inventory": {
                        "bucket_name": b.get("Name"),
                        "region": b.get("Region"),
                    },
                    "assessment": {
                        "inspected_lifecycle": False,
                    },
                },
                "verification_commands": [
                    f"aws s3api get-bucket-lifecycle-configuration --bucket {b.get('Name')}",
                    f"aws s3api get-bucket-location --bucket {b.get('Name')}",
                ],
                "remediation_commands": [],
            }
        )
    return findings


def detect_s3_access_logging_disabled(
    s3_buckets: List[Dict[str, Any]],
) -> List[Dict[str, Any]]:
    """
    Detect S3 buckets that do not have server access logging enabled.

    Access logging is the prerequisite for confident lifecycle policy and
    Intelligent-Tiering decisions: without it, teams cannot know how frequently
    objects are accessed and are paralysed from acting on cost optimisation
    recommendations ("the Egress Trap root cause").

    This detector is offline-safe — it uses the ``logging_enabled`` field
    populated by the scanner (from ``GetBucketLogging``).  When the value is
    ``None`` (API call failed / access denied), the bucket is skipped silently.

    Args:
        s3_buckets: List of S3 bucket dicts from the scanner, expected to carry
            ``logging_enabled`` (bool | None) and ``logging_target_bucket``
            (str | None).

    Returns:
        One finding per bucket where ``logging_enabled is False``.
    """
    findings = []
    for b in s3_buckets:
        logging_enabled: Optional[bool] = b.get("logging_enabled")

        # None means API call failed (access denied, etc.) — skip, don't false-positive
        if logging_enabled is None:
            continue
        if logging_enabled:
            continue

        name: str = b.get("Name") or b.get("id") or "unknown"
        region: Optional[str] = b.get("Region") or b.get("region")

        findings.append(
            {
                "type": "s3_access_logging_disabled",
                "resource_type": "s3",
                "id": name,
                "region": region,
                "estimated_monthly_savings_usd": 0,
                "potential_savings": 0,
                "confidence": 0.9,
                "severity": "low",
                "recommended_action": "enable-access-logging",
                "explanation": (
                    f"Bucket '{name}' has server access logging disabled. "
                    "Without access logs you cannot determine object access frequency, "
                    "making lifecycle policy and Intelligent-Tiering decisions "
                    "unreliable. Enable logging to a separate target bucket before "
                    "acting on storage-cost optimisation recommendations."
                ),
                "evidence": {
                    "inventory": {
                        "bucket_name": name,
                        "region": region,
                        "logging_enabled": False,
                        "logging_target_bucket": b.get("logging_target_bucket"),
                    },
                    "assessment": {
                        "access_logging_present": False,
                        "recommended_next_step": "enable-s3-server-access-logging",
                    },
                },
                "verification_commands": [
                    f"aws s3api get-bucket-logging --bucket {name}",
                ],
                "remediation_commands": [
                    (
                        f"aws s3api put-bucket-logging --bucket {name} "
                        f'--bucket-logging-status \'{{"LoggingEnabled":{{"TargetBucket":"{name}-logs",'
                        f'"TargetPrefix":"access-logs/"}}}}\''
                    ),
                ],
            }
        )
    return findings


def detect_s3_intelligent_tiering_not_configured(
    s3_buckets: List[Dict[str, Any]],
    min_bucket_age_days: int = 7,
) -> List[Dict[str, Any]]:
    """
    Detect S3 buckets without an Intelligent-Tiering configuration applied.

    S3 Intelligent-Tiering automatically moves objects between Frequent Access
    and Infrequent Access tiers based on access patterns — no lifecycle rule
    management required.  It is the lowest-operational-overhead path to
    automatic storage cost savings for workloads with unpredictable access.

    This detector is offline-safe — it uses the ``intelligent_tiering_configured``
    field populated by the scanner (from ``ListBucketIntelligentTieringConfigurations``).
    When the value is ``None`` (access denied), the bucket is skipped.

    Savings estimate: heuristic.  Without object count or bucket size, we cannot
    calculate the monitoring charge offset.  The finding sets
    ``estimated_monthly_savings_usd=0`` and directs the user to verify bucket
    size before acting.

    Args:
        s3_buckets: List of S3 bucket dicts from the scanner.
        min_bucket_age_days: Skip buckets younger than this (very new buckets are
            often empty; Intelligent-Tiering has a 30-day minimum access observation
            window before moving objects to Infrequent tier).

    Returns:
        One finding per bucket where Intelligent-Tiering is not configured.
    """
    from datetime import datetime, timezone

    findings = []
    now = datetime.now(timezone.utc)

    for b in s3_buckets:
        it_configured: Optional[bool] = b.get("intelligent_tiering_configured")

        # None means API call failed — skip
        if it_configured is None:
            continue
        if it_configured:
            continue

        name: str = b.get("Name") or b.get("id") or "unknown"
        region: Optional[str] = b.get("Region") or b.get("region")

        # Skip very new buckets — IT monitoring charge would exceed savings on empty buckets
        creation_date = b.get("CreationDate")
        if creation_date:
            try:
                if isinstance(creation_date, str):
                    cd = datetime.fromisoformat(
                        creation_date.replace("Z", "+00:00").rstrip("()")
                    )
                else:
                    cd = creation_date
                if cd.tzinfo is None:
                    cd = cd.replace(tzinfo=timezone.utc)
                age_days = (now - cd).days
                if age_days < min_bucket_age_days:
                    continue
            except Exception:
                pass  # Unknown age — proceed with finding

        findings.append(
            {
                "type": "s3_intelligent_tiering_not_configured",
                "resource_type": "s3",
                "id": name,
                "region": region,
                "estimated_monthly_savings_usd": 0,
                "estimated_monthly_savings_hint_source": "heuristic",
                "potential_savings": 0,
                "confidence": 0.5,
                "severity": "low",
                "recommended_action": "enable-intelligent-tiering",
                "explanation": (
                    f"Bucket '{name}' has no S3 Intelligent-Tiering configuration. "
                    "Intelligent-Tiering automatically moves objects between Frequent "
                    "and Infrequent Access tiers based on usage — no lifecycle rule "
                    "management required.  Objects not accessed for 30 consecutive days "
                    f"move to Infrequent Access at ${PRICING_S3_IT_MONITORING_PER_1K_OBJECTS:.4f}/1k objects/month "
                    "monitoring charge.  Typical savings: 40\u201360% on infrequently accessed data."
                ),
                "evidence": {
                    "inventory": {
                        "bucket_name": name,
                        "region": region,
                        "intelligent_tiering_configured": False,
                        "access_logging_enabled": b.get("logging_enabled"),
                    },
                    "assessment": {
                        "it_configurations_found": 0,
                        "note": (
                            "Savings estimate requires bucket size and object count. "
                            "Enable S3 Storage Lens or CloudWatch BucketSizeBytes metric "
                            "to quantify before enabling Intelligent-Tiering."
                        ),
                        "prerequisite": (
                            "Consider enabling S3 access logging first "
                            "(see s3_access_logging_disabled finding) to validate "
                            "access patterns before applying Intelligent-Tiering."
                            if not b.get("logging_enabled")
                            else None
                        ),
                    },
                },
                "verification_commands": [
                    f"aws s3api list-bucket-intelligent-tiering-configurations --bucket {name}",
                    f"aws cloudwatch get-metric-statistics --namespace AWS/S3 "
                    f"--metric-name BucketSizeBytes --dimensions "
                    f"Name=BucketName,Value={name} Name=StorageType,Value=StandardStorage "
                    f"--start-time $(date -u -v-2d '+%Y-%m-%dT%H:%M:%S') "
                    f"--end-time $(date -u '+%Y-%m-%dT%H:%M:%S') "
                    f"--period 86400 --statistics Average",
                ],
                "remediation_commands": [
                    (
                        f"aws s3api put-bucket-intelligent-tiering-configuration "
                        f"--bucket {name} "
                        f"--id default-it-config "
                        f"--intelligent-tiering-configuration '"
                        f'{{"Id":"default-it-config","Status":"Enabled",'
                        f'"Tierings":[{{"Days":30,"AccessTier":"ARCHIVE_ACCESS"}}'
                        f"]}}'  "
                        f"  # Review Days threshold before applying; remove ARCHIVE_ACCESS tier if retrieval latency is a concern"
                    ),
                ],
            }
        )
    return findings
