import unittest

from tests.support.harness import PTYMCPTestCase


class SubprocessFlowTests(PTYMCPTestCase):
    def test_spawn_read_wait_close_subprocess(self):
        sid = self.server.pty_spawn(
            "printf sub-ok",
            owner="sub-owner",
            scope="read-write",
            name="sub-live",
        )

        output = self.wait_quiet(sid)
        self.assertEqual(output, "sub-ok")

        status = self.server.pty_status(sid)
        self.assertEqual(status["backend"], "subprocess")
        self.assertFalse(status["running"])
        self.assertEqual(status["exit_code"], 0)
        self.assertFalse(status["recovered"])

        waited = self.server.pty_wait(sid, timeout_ms=1000)
        self.assertFalse(waited["running"])
        self.assertEqual(waited["exit_code"], 0)

        self.server.pty_close(sid)
        self.assertNotIn(sid, self.server.sessions)

    def test_resume_named_live_subprocess_session(self):
        sid = self.server.pty_spawn(
            "sleep 5",
            owner="resume-owner",
            scope="read-write",
            name="resume-live",
        )

        resumed = self.server.pty_resume("resume-live", owner="resume-owner")
        self.assertEqual(resumed["session_id"], sid)
        self.assertEqual(resumed["name"], "resume-live")
        self.assertEqual(resumed["resumed_via"], "name")
        self.assertEqual(resumed["backend"], "subprocess")

    def test_subprocess_is_not_recoverable_after_in_memory_loss(self):
        sid = self.server.pty_spawn(
            "sleep 5",
            owner="recover-owner",
            scope="read-write",
            name="recover-sub",
        )

        session = self.server.sessions.pop(sid)
        try:
            with self.assertRaises(RuntimeError) as ctx:
                self.server.pty_recover("recover-sub", owner="recover-owner")
        finally:
            self.server._cleanup_session(sid, session)

        self.assertIn("no recoverable session named 'recover-sub'", str(ctx.exception))


if __name__ == "__main__":
    unittest.main()
