#!/usr/bin/python3
"""Tests for slpkg.dependency_logger.DependencyLogger.write_deps_log()."""

import json
from pathlib import Path
from unittest.mock import MagicMock

from slpkg.dependency_logger import DependencyLogger


def make_logger(deps_log_file: Path) -> DependencyLogger:
    """Construct DependencyLogger bypassing __init__ (avoids config_load)."""
    dl: DependencyLogger = object.__new__(DependencyLogger)
    dl.deps_log_file = deps_log_file
    dl.utils = MagicMock()
    return dl


# ---------------------------------------------------------------------------
# Filtering: only installed packages are written to log
# ---------------------------------------------------------------------------


def test_only_installed_deps_are_logged(tmp_path: Path) -> None:
    f = tmp_path / "deps.log"
    dl = make_logger(f)
    # yasm installed, libvpx not installed
    dl.utils.is_package_installed.side_effect = lambda name: name == "yasm"
    dl.write_deps_log("ffmpeg", ("yasm", "libvpx"))
    data = json.loads(f.read_text())
    assert data["ffmpeg"] == ["yasm"]


def test_all_deps_installed_all_logged(tmp_path: Path) -> None:
    f = tmp_path / "deps.log"
    dl = make_logger(f)
    dl.utils.is_package_installed.return_value = True
    dl.write_deps_log("ffmpeg", ("yasm", "libvpx", "x264"))
    data = json.loads(f.read_text())
    assert data["ffmpeg"] == ["yasm", "libvpx", "x264"]


def test_no_deps_installed_logs_empty_list(tmp_path: Path) -> None:
    f = tmp_path / "deps.log"
    dl = make_logger(f)
    dl.utils.is_package_installed.return_value = False
    dl.write_deps_log("bash", ("yasm", "libvpx"))
    data = json.loads(f.read_text())
    assert data["bash"] == []


def test_empty_requires_logs_empty_list(tmp_path: Path) -> None:
    f = tmp_path / "deps.log"
    dl = make_logger(f)
    dl.utils.is_package_installed.return_value = True
    dl.write_deps_log("bash", ())
    data = json.loads(f.read_text())
    assert data["bash"] == []


# ---------------------------------------------------------------------------
# JSON file is created/updated correctly
# ---------------------------------------------------------------------------


def test_creates_new_log_file(tmp_path: Path) -> None:
    f = tmp_path / "deps.log"
    assert not f.exists()
    dl = make_logger(f)
    dl.utils.is_package_installed.return_value = True
    dl.write_deps_log("ffmpeg", ("yasm",))
    assert f.exists()


def test_updates_existing_log_file(tmp_path: Path) -> None:
    f = tmp_path / "deps.log"
    # Pre-populate with an existing entry
    f.write_text(json.dumps({"bash": []}), encoding="utf-8")
    dl = make_logger(f)
    dl.utils.read_json_file = MagicMock(return_value={"bash": []})
    dl.utils.is_package_installed.return_value = True
    dl.write_deps_log("ffmpeg", ("yasm",))
    data = json.loads(f.read_text())
    # Both entries should be present
    assert "bash" in data
    assert "ffmpeg" in data
    assert data["ffmpeg"] == ["yasm"]


def test_overwrites_existing_entry_for_same_package(tmp_path: Path) -> None:
    f = tmp_path / "deps.log"
    f.write_text(json.dumps({"ffmpeg": ["old_dep"]}), encoding="utf-8")
    dl = make_logger(f)
    dl.utils.read_json_file = MagicMock(return_value={"ffmpeg": ["old_dep"]})
    dl.utils.is_package_installed.return_value = True
    dl.write_deps_log("ffmpeg", ("yasm",))
    data = json.loads(f.read_text())
    assert data["ffmpeg"] == ["yasm"]


def test_written_file_is_valid_json(tmp_path: Path) -> None:
    f = tmp_path / "deps.log"
    dl = make_logger(f)
    dl.utils.is_package_installed.return_value = True
    dl.write_deps_log("ffmpeg", ("yasm", "libvpx"))
    content = f.read_text(encoding="utf-8")
    parsed = json.loads(content)
    assert isinstance(parsed, dict)
