"""Regression test: _handle_reset_session must clear MMA + RAG state.

Added in test_infrastructure_hardening_20260609 followup. Without these
resets, prior test state pollutes the next session via:
- mma_tier_usage: stale per-tier model/input/output values cause the
  mma_state_update handler to merge with old data, leaving the new
  push's active_tier effectively lost in the GUI render path.
- rag_engine / rag_config: the chroma collection from a prior test
  doesn't get rebuilt, causing RAG queries to return nothing.
"""
import time
import pytest

from src import api_hook_client


@pytest.mark.clean_baseline
def test_reset_session_clears_mma_tier_usage(live_gui) -> None:
 """reset_session() must restore mma_tier_usage to the default (all empty)."""
 client = api_hook_client.ApiHookClient()
 assert client.wait_for_server(timeout=15)
 # Pollute the mma_tier_usage via a mma_state_update push
 client.push_event('mma_state_update', {
  'status': 'running',
  'active_tier': 'Tier 3 (Worker)',
  'tier_usage': {'Tier 1': {'model': 'polluted'}},
  'tickets': []
 })
 # Poll until the polluted entry is visible. Without this, the reset
 # can fire BEFORE the push_event task is processed (async via io_pool
 # + GUI render loop), and the test would falsely pass even if the
 # reset didn't actually clear anything.
 for _ in range(40):
  state = client.get_gui_state()
  mma = state.get('mma_state', {})
  tier1 = mma.get('tier_usage', {}).get('Tier 1', {})
  if tier1.get('model') == 'polluted':
   break
  time.sleep(0.25)
 # Trigger the reset
 client.reset_session()
 # Poll until the polluted entry is gone
 for _ in range(40):
  state = client.get_gui_state()
  mma = state.get('mma_state', {})
  tier1 = mma.get('tier_usage', {}).get('Tier 1', {})
  if tier1.get('model') != 'polluted':
   break
  time.sleep(0.25)
 # Verify the polluted entry is gone
 state = client.get_gui_state()
 mma = state.get('mma_state', {})
 tier1 = mma.get('tier_usage', {}).get('Tier 1', {})
 assert tier1.get('model') != 'polluted', (
  f"reset_session() did not clear mma_tier_usage: {tier1!r}"
 )


@pytest.mark.clean_baseline
def test_reset_session_clears_mma_status(live_gui) -> None:
 """reset_session() must set mma_status back to 'idle'."""
 client = api_hook_client.ApiHookClient()
 assert client.wait_for_server(timeout=15)
 client.push_event('mma_state_update', {
  'status': 'running',
  'active_tier': 'Tier 1 (Orchestrator)',
  'tier_usage': {},
  'tickets': []
 })
 # Poll for the polluted status to be visible BEFORE the reset
 for _ in range(40):
  state = client.get_gui_state()
  if state.get('mma_status') == 'running':
   break
  time.sleep(0.25)
 client.reset_session()
 # Poll for the reset to have taken effect. Without this, the
 # mma_state_update task can fire AFTER the reset, setting status
 # back to 'running' (race condition surfaced in batched live_gui).
 for _ in range(40):
  state = client.get_gui_state()
  if state.get('mma_status') == 'idle':
   break
  time.sleep(0.25)
 assert state.get('mma_status') == 'idle', (
  f"mma_status not reset: {state.get('mma_status')!r}"
 )


@pytest.mark.clean_baseline
def test_reset_session_clears_active_tier(live_gui) -> None:
 """reset_session() must set active_tier back to None."""
 client = api_hook_client.ApiHookClient()
 assert client.wait_for_server(timeout=15)
 client.push_event('mma_state_update', {
  'status': 'running',
  'active_tier': 'Tier 2 (Tech Lead)',
  'tier_usage': {},
  'tickets': []
 })
 # Poll for the polluted active_tier to be visible BEFORE the reset
 for _ in range(40):
  state = client.get_gui_state()
  if state.get('active_tier') == 'Tier 2 (Tech Lead)':
   break
  time.sleep(0.25)
 client.reset_session()
 # Poll for the reset to have taken effect
 for _ in range(40):
  state = client.get_gui_state()
  if state.get('active_tier') is None:
   break
  time.sleep(0.25)
 assert state.get('active_tier') is None, (
  f"active_tier not reset: {state.get('active_tier')!r}"
 )
