"""src.resume_state の単体テスト.

中断したマイグレーションの再開判定（変換済み & ソース未変更なら skip、
ソースが変わっていれば再変換）と状態の永続化往復を検証する。
"""
from __future__ import annotations

import pathlib
import sys

ROOT = pathlib.Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT))

from src.resume_state import (
    FileEntry,
    MigrationState,
    file_hash,
    load_state,
    save_state,
    STATE_FILENAME,
)


def test_is_done_false_for_unknown_file():
    state = MigrationState()
    assert state.is_done("a.py", "anyhash") is False


def test_mark_done_then_is_done_with_same_hash():
    state = MigrationState()
    state.mark_done("a.py", FileEntry(source_hash="H1", source_path="a.py", output_path="a.js", status="ok"))
    assert state.is_done("a.py", "H1") is True


def test_is_done_false_when_hash_changed():
    state = MigrationState()
    state.mark_done("a.py", FileEntry(source_hash="H1", source_path="a.py", output_path="a.js", status="ok"))
    # ソースが変わった（ハッシュ不一致）→ 再変換が必要
    assert state.is_done("a.py", "H2") is False


def test_is_done_false_when_status_error():
    state = MigrationState()
    state.mark_done("a.py", FileEntry(source_hash="H1", source_path="a.py", output_path="", status="error"))
    assert state.is_done("a.py", "H1") is False


def test_file_hash_changes_with_content(tmp_path):
    f = tmp_path / "src.txt"
    f.write_text("hello", encoding="utf-8")
    h1 = file_hash(str(f))
    f.write_text("world", encoding="utf-8")
    h2 = file_hash(str(f))
    assert h1 != h2
    assert len(h1) == 64  # sha256 hex


def test_load_state_missing_returns_empty(tmp_path):
    state = load_state(str(tmp_path))
    assert isinstance(state, MigrationState)
    assert state.files == {}


def test_save_then_load_roundtrip(tmp_path):
    state = MigrationState(source_lang="cobol", target_lang="java")
    state.mark_done("a.cbl", FileEntry(source_hash="H1", source_path="a.cbl", output_path="A.java", status="ok"))
    save_state(str(tmp_path), state)

    assert (tmp_path / STATE_FILENAME).is_file()
    loaded = load_state(str(tmp_path))
    assert loaded.source_lang == "cobol"
    assert loaded.target_lang == "java"
    assert loaded.is_done("a.cbl", "H1") is True


def test_load_state_corrupt_json_returns_empty(tmp_path):
    (tmp_path / STATE_FILENAME).write_text("{broken", encoding="utf-8")
    state = load_state(str(tmp_path))
    assert state.files == {}
