"""Red-phase test: _handle_reset_session must clear project state.

Background: the live_gui session-scoped fixture is shared across all 48 live
tests. Prior tests can leave stale `self.project` and `self.project_paths`
on the controller, which leaks into `test_full_live_workflow` and causes
it to fail with "Project not switched".

The fix: `_handle_reset_session` should reset `self.project` (to a fresh
default dict) and `self.project_paths` (empty list).

Note: `self.active_project_path` is INTENTIONALLY NOT cleared, because
`_do_project_switch` calls `_flush_to_project()` which writes to
`self.active_project_path`. An empty path would raise OSError and
create an infinite re-switch loop. (See the regression discovered
in test_context_sim_live on 2026-06-08.)

This test uses a real AppController() (per the test_view_presets pattern),
pollutes the state, then calls _handle_reset_session and asserts.
"""
import pytest

from src.app_controller import AppController
from src import project_manager


@pytest.fixture
def controller(tmp_path):
 """Build a real AppController with stale project state."""
 proj_path = tmp_path / "stale_project.toml"
 proj_path.write_text("[project]\nname = 'StaleProject'\n")
 ctrl = AppController()
 # Pollute with stale state mimicking what a prior live_gui test leaves behind
 ctrl.project = {
  "project": {"name": "StaleProject", "active_discussion": "main"},
  "files": {"paths": [str(proj_path)]},
  "discussion": {"discussions": {"main": {"history": ["stale msg"]}}},
 }
 ctrl.active_project_path = str(proj_path)
 ctrl.project_paths = [str(proj_path)]
 yield ctrl


def test_handle_reset_session_keeps_active_project_path(controller):
 """Active project path is intentionally NOT cleared.

 `_do_project_switch` writes to it via `_flush_to_project`; clearing it
 causes OSError on the next project switch. (Regression: test_context_sim_live
 on 2026-06-08.)
 """
 assert controller.active_project_path.endswith("stale_project.toml")  # precondition
 controller._handle_reset_session()
 assert controller.active_project_path.endswith("stale_project.toml"), (
  f"_handle_reset_session should NOT clear active_project_path "
  f"(got {controller.active_project_path!r})"
 )


def test_handle_reset_session_clears_project_paths(controller):
 """project_paths list must be cleared (or reset to defaults)."""
 assert len(controller.project_paths) == 1  # precondition
 controller._handle_reset_session()
 assert controller.project_paths != [str(controller.active_project_path)], (
  f"_handle_reset_session did not clear project_paths "
  f"(still {controller.project_paths!r})"
 )


def test_handle_reset_session_resets_project_to_valid_default(controller):
 """self.project must be a valid (non-stale) project dict after reset."""
 assert controller.project["project"]["name"] == "StaleProject"  # precondition
 controller._handle_reset_session()
 name = controller.project.get("project", {}).get("name", "")
 assert name != "StaleProject", (
  f"_handle_reset_session did not reset self.project (still {name!r})"
 )
 # And it must still be a usable project dict
 assert isinstance(controller.project, dict)
 assert "project" in controller.project


def test_handle_reset_session_clears_project_switch_state(controller):
 """The project-switch state machine must be reset so a hung switch
 from a prior test does not block the next session.

 `is_project_stale()` must return False after reset, otherwise the next
 `btn_project_new_automated` click is queued behind the hung switch
 and `is_project_stale()` keeps returning True, blocking AI ops
 (`_handle_generate_send` returns 'project switch in progress; AI ops disabled').
 """
 # Simulate a prior hung switch
 controller._project_switch_in_progress = True
 controller._project_switch_pending_path = "/some/old/path.toml"
 controller._project_switch_error = "stale error from hung switch"
 assert controller.is_project_stale()  # precondition
 controller._handle_reset_session()
 assert controller._project_switch_in_progress is False, (
  f"_project_switch_in_progress not cleared: {controller._project_switch_in_progress}"
 )
 assert controller._project_switch_pending_path is None, (
  f"_project_switch_pending_path not cleared: {controller._project_switch_pending_path}"
 )
 assert controller._project_switch_error is None, (
  f"_project_switch_error not cleared: {controller._project_switch_error}"
 )
 assert not controller.is_project_stale(), (
  f"is_project_stale() still True after reset: "
  f"in_progress={controller._project_switch_in_progress}, "
  f"pending={controller._project_switch_pending_path}"
 )

