"""Contract tests for SDK background result types.

Validates that ClusteringResult, CommunityDetectionResult, ConsolidationResult,
EntityImportanceResult, SummaryRefreshResult, and MemifyResult have all fields
that scheduler.py and admin.py access.

== Consumer Field Mapping (source of truth) ==

ClusteringResult — scheduler.py accesses:
  .clusters_created, .clusters_reinforced, .facts_assigned

CommunityDetectionResult — scheduler.py accesses:
  .skipped, .communities_created, .communities_reinforced

ConsolidationResult — scheduler.py accesses:
  .skipped, .events_processed, .observations_created

EntityImportanceResult — scheduler.py accesses:
  .entities_scored, .top_entities (for top_entity_key via top_entities[0])

SummaryRefreshResult — scheduler.py accesses:
  .summaries_refreshed, .summaries_skipped

MemifyResult — scheduler.py accesses:
  .facts_scored, .facts_marked_stale, .edges_reinforced
  admin.py also accesses: .merges_executed
"""

from __future__ import annotations

from arandu.background import (
    ClusteringResult,
    CommunityDetectionResult,
    ConsolidationResult,
    EntityImportanceResult,
    MemifyResult,
    SummaryRefreshResult,
)

# ===========================================================================
# ClusteringResult
# ===========================================================================


def test_clustering_result_has_scheduler_fields():
    r = ClusteringResult()
    assert hasattr(r, "clusters_created")
    assert hasattr(r, "clusters_reinforced")
    assert hasattr(r, "facts_assigned")


def test_clustering_result_defaults_are_zero():
    r = ClusteringResult()
    assert r.clusters_created == 0
    assert r.clusters_reinforced == 0
    assert r.facts_assigned == 0


def test_clustering_result_accepts_values():
    r = ClusteringResult(clusters_created=5, clusters_reinforced=3, facts_assigned=20)
    assert r.clusters_created == 5
    assert r.clusters_reinforced == 3
    assert r.facts_assigned == 20


# ===========================================================================
# CommunityDetectionResult
# ===========================================================================


def test_community_detection_result_has_scheduler_fields():
    r = CommunityDetectionResult()
    assert hasattr(r, "skipped")
    assert hasattr(r, "communities_created")
    assert hasattr(r, "communities_reinforced")
    assert hasattr(r, "clusters_in_communities")


def test_community_detection_result_skipped_default():
    r = CommunityDetectionResult()
    assert r.skipped is False


def test_community_detection_result_skip_reason():
    r = CommunityDetectionResult(skipped=True, skip_reason="not enough clusters")
    assert r.skipped is True
    assert r.skip_reason == "not enough clusters"


# ===========================================================================
# ConsolidationResult
# ===========================================================================


def test_consolidation_result_has_scheduler_fields():
    r = ConsolidationResult()
    assert hasattr(r, "skipped")
    assert hasattr(r, "events_processed")
    assert hasattr(r, "observations_created")
    assert hasattr(r, "observations_reinforced")


def test_consolidation_result_defaults():
    r = ConsolidationResult()
    assert r.skipped is False
    assert r.events_processed == 0
    assert r.observations_created == 0


# ===========================================================================
# EntityImportanceResult
# ===========================================================================


def test_entity_importance_result_has_scheduler_fields():
    r = EntityImportanceResult()
    assert hasattr(r, "entities_scored")
    assert hasattr(r, "top_entities")


def test_entity_importance_result_top_entities_is_list():
    r = EntityImportanceResult()
    assert isinstance(r.top_entities, list)


def test_entity_importance_result_top_entity_extraction():
    """scheduler.py derives top_entity_key from top_entities[0][0]."""
    r = EntityImportanceResult(
        entities_scored=3,
        top_entities=[("person::alice", 0.95), ("person::bob", 0.80)],
    )
    assert r.entities_scored == 3
    top_key = r.top_entities[0][0] if r.top_entities else None
    assert top_key == "person::alice"


# ===========================================================================
# SummaryRefreshResult
# ===========================================================================


def test_summary_refresh_result_has_scheduler_fields():
    r = SummaryRefreshResult()
    assert hasattr(r, "summaries_refreshed")
    assert hasattr(r, "summaries_skipped")


def test_summary_refresh_result_defaults():
    r = SummaryRefreshResult()
    assert r.summaries_refreshed == 0
    assert r.summaries_skipped == 0


# ===========================================================================
# MemifyResult
# ===========================================================================


def test_memify_result_has_scheduler_fields():
    r = MemifyResult()
    assert hasattr(r, "facts_scored")
    assert hasattr(r, "facts_marked_stale")
    assert hasattr(r, "edges_reinforced")


def test_memify_result_has_admin_fields():
    """admin.py also accesses merges_executed."""
    r = MemifyResult()
    assert hasattr(r, "merges_executed")


def test_memify_result_defaults():
    r = MemifyResult()
    assert r.facts_scored == 0
    assert r.facts_marked_stale == 0
    assert r.edges_reinforced == 0
    assert r.merges_executed == 0


def test_memify_result_accepts_values():
    r = MemifyResult(facts_scored=100, facts_marked_stale=5, edges_reinforced=20, merges_executed=2)
    assert r.facts_scored == 100
    assert r.merges_executed == 2
