"""Baseline management — learn and track what is considered "normal" state.

Baselines allow teams to accept known deviations from IaC state,
preventing them from being flagged as drift on subsequent scans.
"""

from __future__ import annotations

import time
from typing import Any, Optional

from ..store import BaselineEntry, DriftStore


class BaselineManager:
    """Manage drift baselines — known-good or accepted deviations.

    Baselines suppress drift alerts for specific resource/attribute
    combinations that have been reviewed and accepted by the team.
    """

    def __init__(self, store: DriftStore) -> None:
        self.store = store

    def accept_drift(
        self,
        resource_id: str,
        resource_type: str,
        attribute: str,
        accepted_value: Any,
        reason: str,
        ttl_days: Optional[int] = None,
    ) -> BaselineEntry:
        """Accept a drift as a baseline.

        Args:
            resource_id: Cloud resource ID.
            resource_type: Resource type.
            attribute: The drifted attribute to accept.
            accepted_value: The accepted value.
            reason: Human-readable reason for acceptance.
            ttl_days: Optional time-to-live in days. After expiry,
                     the drift will be flagged again.

        Returns:
            The created BaselineEntry.
        """
        entry = BaselineEntry(
            resource_id=resource_id,
            resource_type=resource_type,
            attribute=attribute,
            accepted_value=accepted_value,
            reason=reason,
            created_at=time.time(),
            expires_at=time.time() + (ttl_days * 86400) if ttl_days else None,
        )
        self.store.save_baseline(entry)
        return entry

    def is_baselined(self, resource_id: str, attribute: str) -> bool:
        """Check if a resource/attribute combination is baselined.

        Args:
            resource_id: Cloud resource ID.
            attribute: The attribute name.

        Returns:
            True if an active (non-expired) baseline exists.
        """
        baseline = self.store.get_baseline(resource_id, attribute)
        return baseline is not None

    def get_all(self) -> list[dict[str, Any]]:
        """Get all active baselines."""
        return self.store.get_all_baselines()

    def remove_baseline(self, resource_id: str, attribute: str) -> bool:
        """Remove a baseline entry.

        Returns:
            True if a baseline was removed, False if none existed.
        """
        # Check existence first
        if not self.is_baselined(resource_id, attribute):
            return False
        # Remove by setting expiry to past
        entry = BaselineEntry(
            resource_id=resource_id,
            resource_type="",
            attribute=attribute,
            accepted_value=None,
            reason="removed",
            created_at=time.time(),
            expires_at=time.time() - 1,  # Already expired
        )
        self.store.save_baseline(entry)
        return True

    def filter_baselined_drifts(
        self,
        drifts: list[dict[str, Any]],
    ) -> list[dict[str, Any]]:
        """Filter out drifts that have active baselines.

        Args:
            drifts: List of drift records (dicts with resource_id and attribute).

        Returns:
            Filtered list excluding baselined drifts.
        """
        return [
            d for d in drifts
            if not self.is_baselined(d.get("resource_id", ""), d.get("attribute", ""))
        ]
