"""Tests for #823 — _profileDefaultWorkspace persists after newSession() (#804 follow-up)

Root cause: newSession() consumed S._profileDefaultWorkspace for the one-shot
profile-switch semantic (setting it to null after the first new session). This
caused the blank-page default workspace display to regress after any session
was created and then deleted.

Fix: introduce S._profileSwitchWorkspace as the dedicated one-shot flag for
profile-switch semantics; S._profileDefaultWorkspace is now persistent.
"""
import pathlib
import re

REPO = pathlib.Path(__file__).parent.parent


def read(rel):
    return (REPO / rel).read_text(encoding='utf-8')


class TestProfileDefaultWorkspacePersistence:
    """_profileDefaultWorkspace must NOT be nulled by newSession()."""

    def test_new_session_does_not_null_profile_default_workspace(self):
        src = read('static/sessions.js')
        m = re.search(r'async function newSession\(.*?\n\}', src, re.DOTALL)
        assert m, "newSession not found"
        fn = m.group(0)
        # The old consume pattern must be gone
        assert '_profileDefaultWorkspace=null' not in fn and \
               '_profileDefaultWorkspace = null' not in fn, (
            "newSession must NOT null S._profileDefaultWorkspace — it is the persistent "
            "boot/settings default used for blank-page display after session delete (#823)"
        )

    def test_new_session_uses_dedicated_switch_workspace_flag(self):
        src = read('static/sessions.js')
        m = re.search(r'async function newSession\(.*?\n\}', src, re.DOTALL)
        assert m
        fn = m.group(0)
        assert '_profileSwitchWorkspace' in fn, (
            "newSession must read S._profileSwitchWorkspace for the one-shot "
            "profile-switch inherit, not S._profileDefaultWorkspace"
        )
        # It should null the switch flag, not the default
        assert '_profileSwitchWorkspace=null' in fn or '_profileSwitchWorkspace = null' in fn, (
            "newSession must null S._profileSwitchWorkspace after consuming it"
        )

    def test_new_session_still_inherits_default_workspace(self):
        """newSession must still pass a workspace to /api/session/new —
        now via the _profileSwitchWorkspace → current session → _profileDefaultWorkspace chain."""
        src = read('static/sessions.js')
        m = re.search(r'async function newSession\(.*?\n\}', src, re.DOTALL)
        assert m
        fn = m.group(0)
        # inheritWs must be computed and passed to /api/session/new
        assert 'inheritWs' in fn or 'inherit' in fn.lower(), (
            "newSession must compute an inheritWs from switch/current/default workspace"
        )
        assert '_profileDefaultWorkspace' in fn, (
            "newSession must fall through to S._profileDefaultWorkspace as last resort"
        )


class TestProfileSwitchWorkspaceSetter:
    """panels.js must set _profileSwitchWorkspace on profile switch."""

    def test_panels_sets_profile_switch_workspace(self):
        src = read('static/panels.js')
        # Find the profile-switch workspace block
        assert 'S._profileSwitchWorkspace' in src, (
            "panels.js must set S._profileSwitchWorkspace during profile switch "
            "so newSession() can apply it to the first new session"
        )

    def test_panels_still_sets_profile_default_workspace(self):
        src = read('static/panels.js')
        assert 'S._profileDefaultWorkspace = data.default_workspace' in src, (
            "panels.js must still set S._profileDefaultWorkspace (persistent default) "
            "alongside S._profileSwitchWorkspace"
        )

    def test_both_set_together_in_same_block(self):
        src = read('static/panels.js')
        default_pos = src.find('S._profileDefaultWorkspace = data.default_workspace')
        switch_pos = src.find('S._profileSwitchWorkspace = data.default_workspace')
        assert default_pos != -1, "S._profileDefaultWorkspace setter not found"
        assert switch_pos != -1, "S._profileSwitchWorkspace setter not found"
        # Both must be set within 200 chars of each other (same block)
        assert abs(default_pos - switch_pos) < 300, (
            "_profileDefaultWorkspace and _profileSwitchWorkspace must be set "
            "together in the same profile-switch workspace block"
        )


    def test_switch_to_workspace_clears_profile_switch_workspace(self):
        """Opus Q4: when the user manually changes workspace, the pending one-shot
        switch flag should be cleared so a subsequent newSession() inherits the
        user's explicit choice rather than the stale profile-switch default."""
        src = read('static/panels.js')
        m = re.search(r'async function switchToWorkspace\(.*?\n\}', src, re.DOTALL)
        assert m, "switchToWorkspace not found"
        fn = m.group(0)
        assert '_profileSwitchWorkspace=null' in fn or '_profileSwitchWorkspace = null' in fn, (
            "switchToWorkspace must null S._profileSwitchWorkspace after a manual switch "
            "so the next newSession() inherits the user's explicit workspace choice"
        )


class TestBlankPageAfterSessionDelete:
    """After all sessions are deleted, blank page must still show default workspace."""

    def test_sync_workspace_displays_reads_profile_default(self):
        """syncWorkspaceDisplays relies on S._profileDefaultWorkspace which must
        still be set after a session is created and deleted."""
        src = read('static/panels.js')
        m = re.search(r'function syncWorkspaceDisplays\(\)\{.*?\n\}', src, re.DOTALL)
        assert m, "syncWorkspaceDisplays not found"
        fn = m.group(0)
        assert '_profileDefaultWorkspace' in fn, (
            "syncWorkspaceDisplays must read S._profileDefaultWorkspace as fallback"
        )

    def test_prompt_new_file_reads_profile_default(self):
        """promptNewFile on blank page reads _profileDefaultWorkspace which must
        be non-null even after a newSession() + deleteSession() cycle."""
        src = read('static/ui.js')
        m = re.search(r'async function promptNewFile\(\)\{.*?\n\}', src, re.DOTALL)
        assert m, "promptNewFile not found"
        fn = m.group(0)
        assert '_profileDefaultWorkspace' in fn, (
            "promptNewFile must read S._profileDefaultWorkspace (must persist after newSession)"
        )
