"""Mock implementations for ACMS context CLI tests.

Provides mock ContextTierService and container for use in Behave step
definitions. All test doubles must reside in features/mocks/ per
CONTRIBUTING.md.
"""

from __future__ import annotations

from typing import Any
from unittest.mock import MagicMock

from cleveragents.domain.models.acms.tiers import (
    ContextTier,
    TierBudget,
    TieredFragment,
    TierMetrics,
)


def make_tiered_fragment(
    fragment_id: str,
    resource_id: str = "",
    tier: ContextTier = ContextTier.HOT,
    token_count: int = 100,
    project_name: str = "test_project",
    tag: str | None = None,
) -> TieredFragment:
    """Create a TieredFragment for testing.

    Args:
        fragment_id: Unique identifier for the fragment.
        resource_id: Resource path (e.g. src/module.py).
        tier: Storage tier (hot/warm/cold).
        token_count: Token count of the fragment content.
        project_name: Project scope for isolation.
        tag: Optional tag value stored in metadata.

    Returns:
        A TieredFragment configured for testing.
    """
    metadata: dict[str, Any] = {}
    if tag is not None:
        metadata["tag"] = tag
    return TieredFragment(
        fragment_id=fragment_id,
        content=f"# Content for {resource_id}",
        tier=tier,
        resource_id=resource_id,
        project_name=project_name,
        token_count=token_count,
        metadata=metadata,
    )


def make_mock_tier_service(
    fragments: list[TieredFragment] | None = None,
    scoped_fragments: list[TieredFragment] | None = None,
    removed_count: int = 0,
) -> MagicMock:
    """Create a mock ContextTierService with pre-configured return values.

    Args:
        fragments: Return value for get_all_fragments().
        scoped_fragments: Return value for get_scoped_view().
        removed_count: Not used directly (removal is simulated).

    Returns:
        A MagicMock configured to behave like a ContextTierService.
    """
    mock_service = MagicMock()
    mock_service.get_all_fragments.return_value = fragments or []
    mock_service.get_scoped_view.return_value = scoped_fragments or []
    mock_service.get_metrics.return_value = TierMetrics(
        hot_count=len([f for f in (fragments or []) if f.tier == ContextTier.HOT]),
        warm_count=len([f for f in (fragments or []) if f.tier == ContextTier.WARM]),
        cold_count=len([f for f in (fragments or []) if f.tier == ContextTier.COLD]),
    )
    mock_service.budget = TierBudget()
    mock_service._lock = MagicMock()
    mock_service._lock.__enter__ = MagicMock(return_value=None)
    mock_service._lock.__exit__ = MagicMock(return_value=False)
    mock_service._remove_from_all = MagicMock()
    return mock_service


def make_mock_container(mock_tier_service: MagicMock) -> MagicMock:
    """Create a mock DI container that returns the given tier service.

    Args:
        mock_tier_service: The mock service to return from context_tier_service().

    Returns:
        A MagicMock configured to behave like the DI container.
    """
    mock_container = MagicMock()
    mock_container.context_tier_service.return_value = mock_tier_service
    return mock_container
