from __future__ import annotations

import hashlib
import time
from pathlib import Path
from unittest.mock import patch

import pytest

from oh_my_linear.server import (
    _DEBUG_DIR,
    _RECONNECT_FLAG,
    _RECONNECT_MAX_AGE_S,
    _is_reconnect,
    _on_shutdown_signal,
)


class TestIsReconnect:
    def test_returns_true_for_fresh_flag(self, tmp_path: Path) -> None:
        flag = tmp_path / "reconnect"
        flag.write_text(f"{time.time()}\n")

        with patch("oh_my_linear.server._RECONNECT_FLAG", flag):
            assert _is_reconnect() is True

        assert not flag.exists()  # flag should be cleaned up

    def test_returns_false_for_stale_flag(self, tmp_path: Path) -> None:
        flag = tmp_path / "reconnect"
        flag.write_text("old\n")
        # Set mtime to 20 seconds ago
        import os
        old_time = time.time() - 20
        os.utime(flag, (old_time, old_time))

        with patch("oh_my_linear.server._RECONNECT_FLAG", flag):
            assert _is_reconnect() is False

        assert not flag.exists()  # flag should still be cleaned up

    def test_returns_false_when_no_flag(self, tmp_path: Path) -> None:
        flag = tmp_path / "reconnect"  # does not exist

        with patch("oh_my_linear.server._RECONNECT_FLAG", flag):
            assert _is_reconnect() is False


class TestOnShutdownSignal:
    def test_always_writes_reconnect_flag(self, tmp_path: Path) -> None:
        debug_dir = tmp_path / "debug"

        with (
            patch("oh_my_linear.server._DEBUG_DIR", debug_dir),
            patch("oh_my_linear.server._RECONNECT_FLAG", debug_dir / "reconnect"),
            patch("oh_my_linear.server._shutdown"),
            patch("oh_my_linear.server.os._exit"),
        ):
            _on_shutdown_signal()

        assert (debug_dir / "sigterm").exists()
        assert (debug_dir / "reconnect").exists()

        content = (debug_dir / "reconnect").read_text().strip()
        ts = float(content)
        assert time.time() - ts < 2.0

    def test_always_calls_os_exit(self, tmp_path: Path) -> None:
        debug_dir = tmp_path / "debug"

        with (
            patch("oh_my_linear.server._DEBUG_DIR", debug_dir),
            patch("oh_my_linear.server._RECONNECT_FLAG", debug_dir / "reconnect"),
            patch("oh_my_linear.server._shutdown"),
            patch("oh_my_linear.server.os._exit") as mock_exit,
        ):
            _on_shutdown_signal()

        mock_exit.assert_called_once_with(0)

    def test_writes_sigterm_breadcrumb(self, tmp_path: Path) -> None:
        debug_dir = tmp_path / "debug"

        with (
            patch("oh_my_linear.server._DEBUG_DIR", debug_dir),
            patch("oh_my_linear.server._RECONNECT_FLAG", debug_dir / "reconnect"),
            patch("oh_my_linear.server._shutdown"),
            patch("oh_my_linear.server.os._exit"),
        ):
            _on_shutdown_signal()

        assert (debug_dir / "sigterm").exists()
