"""Disk-space pre-check in `download_journal_data`."""

import os
from unittest.mock import patch

import pytest

from local_deep_research.journal_quality.downloader import (
    download_journal_data,
)


@pytest.fixture
def tmp_data_dir(tmp_path):
    with patch(
        "local_deep_research.journal_quality.downloader._get_data_dir",
        return_value=tmp_path,
    ):
        yield tmp_path


def _fake_disk_usage(free_bytes):
    class _Usage:
        total = 10 * 1024**3
        used = total - free_bytes
        free = free_bytes

    return _Usage()


def _stamp_live_sentinel(path):
    """Write the current PID into the sentinel so the downloader's
    PID-based liveness check treats it as "owner alive" and
    short-circuits with "already in progress" rather than reclaiming
    it as orphan. An empty `.touch()`'d sentinel fails the int()
    parse in `_sentinel_owner_alive` and is now correctly treated
    as orphan.
    """
    path.write_text(str(os.getpid()))


def test_disk_space_below_threshold_refuses_download(tmp_data_dir):
    with patch(
        "shutil.disk_usage",
        return_value=_fake_disk_usage(500 * 1024**2),  # 500 MB free
    ):
        success, msg = download_journal_data(force=True)
    assert success is False
    assert "Insufficient disk space" in msg
    assert "0.5 GB available" in msg


def test_disk_space_above_threshold_proceeds_past_check(tmp_data_dir):
    # Simulate a concurrent download in progress so we can assert that
    # the disk check was cleared (we wouldn't reach this error otherwise).
    sentinel = tmp_data_dir / ".downloading"
    _stamp_live_sentinel(sentinel)
    with patch(
        "shutil.disk_usage",
        return_value=_fake_disk_usage(5 * 1024**3),  # 5 GB free
    ):
        success, msg = download_journal_data(force=True)
    assert success is False
    assert "already in progress" in msg


def test_disk_usage_os_error_does_not_block_download(tmp_data_dir):
    sentinel = tmp_data_dir / ".downloading"
    _stamp_live_sentinel(sentinel)
    with patch("shutil.disk_usage", side_effect=OSError("permission denied")):
        success, msg = download_journal_data(force=True)
    # OSError must not short-circuit — the function logs and proceeds,
    # so we still hit the sentinel short-circuit below.
    assert success is False
    assert "already in progress" in msg
