"""Tests for status.py journal functions: append_journal_entry, load_journal."""

import json
from pathlib import Path

import pytest

import status


class TestAppendJournalEntry:
    def test_creates_file_and_appends(self, project_dir: Path):
        status.append_journal_entry(project_dir, {"iter": 1, "outcome": "productive"})
        jpath = project_dir / ".autobuilder" / "journal.jsonl"
        assert jpath.exists()
        lines = jpath.read_text().strip().splitlines()
        assert len(lines) == 1
        entry = json.loads(lines[0])
        assert entry["iter"] == 1
        assert entry["outcome"] == "productive"
        assert "ts" in entry

    def test_appends_multiple_entries(self, project_dir: Path):
        status.append_journal_entry(project_dir, {"iter": 1})
        status.append_journal_entry(project_dir, {"iter": 2})
        status.append_journal_entry(project_dir, {"iter": 3})
        jpath = project_dir / ".autobuilder" / "journal.jsonl"
        lines = jpath.read_text().strip().splitlines()
        assert len(lines) == 3

    def test_sets_default_timestamp(self, project_dir: Path):
        status.append_journal_entry(project_dir, {"iter": 1})
        jpath = project_dir / ".autobuilder" / "journal.jsonl"
        entry = json.loads(jpath.read_text().strip())
        assert isinstance(entry["ts"], int)
        assert entry["ts"] > 0

    def test_preserves_explicit_timestamp(self, project_dir: Path):
        status.append_journal_entry(project_dir, {"iter": 1, "ts": 12345})
        jpath = project_dir / ".autobuilder" / "journal.jsonl"
        entry = json.loads(jpath.read_text().strip())
        assert entry["ts"] == 12345

    def test_creates_parent_dirs(self, tmp_path: Path):
        project = tmp_path / "deep" / "nested" / "project"
        status.append_journal_entry(project, {"iter": 1})
        jpath = project / ".autobuilder" / "journal.jsonl"
        assert jpath.exists()


class TestLoadJournal:
    def test_empty_when_no_file(self, project_dir: Path):
        assert status.load_journal(project_dir) == []

    def test_loads_single_entry(self, project_dir: Path):
        status.append_journal_entry(project_dir, {"iter": 1, "outcome": "idle"})
        entries = status.load_journal(project_dir)
        assert len(entries) == 1
        assert entries[0]["iter"] == 1

    def test_loads_multiple_entries(self, project_dir: Path):
        for i in range(5):
            status.append_journal_entry(project_dir, {"iter": i + 1})
        entries = status.load_journal(project_dir)
        assert len(entries) == 5
        assert entries[0]["iter"] == 1
        assert entries[4]["iter"] == 5

    def test_respects_max_entries(self, project_dir: Path):
        for i in range(10):
            status.append_journal_entry(project_dir, {"iter": i + 1})
        entries = status.load_journal(project_dir, max_entries=3)
        assert len(entries) == 3
        assert entries[0]["iter"] == 8
        assert entries[2]["iter"] == 10

    def test_skips_malformed_lines(self, project_dir: Path):
        jpath = project_dir / ".autobuilder" / "journal.jsonl"
        jpath.parent.mkdir(parents=True, exist_ok=True)
        jpath.write_text(
            '{"iter":1}\n'
            "this is not json\n"
            '{"iter":3}\n',
            encoding="utf-8",
        )
        entries = status.load_journal(project_dir)
        assert len(entries) == 2
        assert entries[0]["iter"] == 1
        assert entries[1]["iter"] == 3

    def test_skips_blank_lines(self, project_dir: Path):
        jpath = project_dir / ".autobuilder" / "journal.jsonl"
        jpath.parent.mkdir(parents=True, exist_ok=True)
        jpath.write_text(
            '{"iter":1}\n\n\n{"iter":2}\n',
            encoding="utf-8",
        )
        entries = status.load_journal(project_dir)
        assert len(entries) == 2

    def test_returns_empty_on_empty_file(self, project_dir: Path):
        jpath = project_dir / ".autobuilder" / "journal.jsonl"
        jpath.parent.mkdir(parents=True, exist_ok=True)
        jpath.write_text("", encoding="utf-8")
        assert status.load_journal(project_dir) == []


class TestJournalPath:
    def test_filename_constant(self):
        assert status.JOURNAL_FILENAME == "journal.jsonl"

    def test_journal_path(self, project_dir: Path):
        expected = project_dir / ".autobuilder" / "journal.jsonl"
        assert status._journal_path(project_dir) == expected
