import pathlib
import unittest


class StopStateContractTests(unittest.TestCase):
    def test_stop_declares_a_json_content_type_before_bootstrapping(self):
        endpoint = (
            pathlib.Path(__file__).parents[1] / "api" / "private" / "stop.php"
        ).read_text(encoding="utf-8")

        self.assertTrue(endpoint.startswith("<?php\nheader('Content-Type: application/json; charset=utf-8');"))
        self.assertNotIn("Content-type => text/html", endpoint)

    def test_stop_keeps_price_queue_compatible_with_non_null_sql_column(self):
        test_class = pathlib.Path(__file__).parents[1] / "classes" / "Test.php"
        source = test_class.read_text(encoding="utf-8")

        self.assertIn(
            'jsonset("test:{$this->test_id}", "$.price_queue", json_encode(""))',
            source,
        )
        self.assertNotIn(
            'jsonset("test:{$this->test_id}", "$.price_queue", "null")',
            source,
        )

    def test_stop_records_the_wall_clock_end_before_persisting_terminal_state(self):
        test_class = pathlib.Path(__file__).parents[1] / "classes" / "Test.php"
        source = test_class.read_text(encoding="utf-8")

        stop_start = source.index("public function stop($finalize_runtime=true)")
        stop_source = source[stop_start: source.index("public function UpdateStartEquity", stop_start)]

        self.assertIn('$terminal_end_time = time();', stop_source)
        self.assertIn(
            'jsonset("test:{$this->test_id}", "$.end_time", $terminal_end_time)',
            stop_source,
        )
        self.assertLess(
            stop_source.index('jsonset("test:{$this->test_id}", "$.end_time", $terminal_end_time)'),
            stop_source.rindex('$test_data = $this->get();'),
        )

    def test_terminal_stop_acknowledges_the_completed_test_without_false_error(self):
        endpoint = (
            pathlib.Path(__file__).parents[1] / "api" / "private" / "stop.php"
        ).read_text(encoding="utf-8")

        terminal_state = "$terminal_test_data = $test->get(false);"
        terminal_ack = "if ((int)$terminal_test_data['status'] === 2)"
        running_guard = "ErrorHandlerBee::isTrue($test_data['status'] == 1"
        self.assertIn(terminal_state, endpoint)
        self.assertIn(terminal_ack, endpoint)
        self.assertIn("'already_stopped'", endpoint)
        self.assertLess(endpoint.index(terminal_state), endpoint.index(terminal_ack))
        self.assertLess(endpoint.index(terminal_ack), endpoint.index(running_guard))

    def test_natural_completion_releases_host_and_closes_history(self):
        test_class = pathlib.Path(__file__).parents[1] / "classes" / "Test.php"
        source = test_class.read_text(encoding="utf-8")

        self.assertIn("private function finalize_runtime()", source)
        self.assertIn("GREATEST(`bot_hosts`.`active_bots` - 1, 0)", source)
        self.assertIn("`bee_tests`.`bot_host` = 0", source)
        self.assertIn("`bee_test_history`", source)
        self.assertIn("`finished_at` = UTC_TIMESTAMP()", source)
        self.assertIn("$this->finalize_runtime()", source)
        self.assertIn("public function stop($finalize_runtime=true)", source)
        endpoint = (
            pathlib.Path(__file__).parents[1] / "api" / "private" / "stop.php"
        ).read_text(encoding="utf-8")
        self.assertIn("$test->stop(true)", endpoint)


if __name__ == "__main__":
    unittest.main()
