"""Unit tests for journal cache mixin behavior."""

from __future__ import annotations

from pathlib import Path
from typing import Any

from cascade_fm.core.cache.cache_journal import JournalCacheMixin
from cascade_fm.executor import OperationExecutor
from cascade_fm.operations.base import Operation


class DummyJournalOperation(JournalCacheMixin, Operation):
    """Dummy operation using journal cache hooks."""

    execute_calls = 0

    @property
    def name(self) -> str:
        return "dummy_journal"

    @property
    def label(self) -> str:
        return "Dummy Journal"

    @property
    def description(self) -> str:
        return "Dummy operation for journal cache tests"

    def _can_execute_without_params(self) -> bool:
        return True

    def _execute_impl(self, files: list[Path], **params: Any) -> list[Path]:
        DummyJournalOperation.execute_calls += 1
        return files


class TestJournalCache:
    """Tests for journal-based operation-owned cache hooks."""

    def test_journal_cache_hit_and_metadata_invalidation(self, tmp_path: Path) -> None:
        """Second run should hit cache; metadata change should invalidate cache."""
        DummyJournalOperation.execute_calls = 0
        executor = OperationExecutor()
        operation = DummyJournalOperation()

        file_path = tmp_path / "input.txt"
        file_path.write_text("v1", encoding="utf-8")

        params = {"mode": "journal"}

        first = executor.execute(operation, [file_path], params)
        assert first.success
        assert DummyJournalOperation.execute_calls == 1

        second = executor.execute(operation, [file_path], params)
        assert second.success
        assert DummyJournalOperation.execute_calls == 1
        second_call_count = DummyJournalOperation.execute_calls

        file_path.write_text("v2-changed-size", encoding="utf-8")

        third = executor.execute(operation, [file_path], params)
        assert third.success
        assert DummyJournalOperation.execute_calls > second_call_count
