"""Tests for KOReader-compatible file hash generation."""

import pytest
from httpx import AsyncClient
from pathlib import Path


# Known KOReader hashes for test files
TEST_FILES = {
    "Moby Dick; Or, The Whale - Herman Melville.epub": {
        "path": Path("tests/data_files/Moby Dick; Or, The Whale - Herman Melville.epub"),
        "hash": "ceeef909ec65653ba77e1380dff998fb",
        "content_type": "application/epub+zip",
    },
    "Calculus Made Easy - Silvanus Thompson.pdf": {
        "path": Path("tests/data_files/Calculus Made Easy - Silvanus Thompson.pdf"),
        "hash": "ace67d512efd1efdea20f3c2436b6075",
        "content_type": "application/pdf",
    },
}


@pytest.mark.parametrize(
    ("book_name",),
    [(name,) for name in TEST_FILES.keys()],
)
async def test_upload_book_generates_correct_hash(
    authenticated_client: AsyncClient,
    book_name: str,
) -> None:
    """Test that uploading a book generates the correct KOReader-compatible hash."""
    book_info = TEST_FILES[book_name]
    file_content = book_info["path"].read_bytes()

    files = [("files", (book_name, file_content, book_info["content_type"]))]
    data = {"library_id": "1"}

    response = await authenticated_client.post(
        "/books?library_id=1",
        files=files,
        data=data,
    )

    assert response.status_code == 201
    book_data = response.json()

    assert len(book_data["files"]) == 1
    file_metadata = book_data["files"][0]

    assert "hash" in file_metadata
    assert file_metadata["hash"] == book_info["hash"]


async def test_add_file_to_book_generates_correct_hash(
    authenticated_client: AsyncClient,
) -> None:
    """Test that adding a file to an existing book generates the correct hash."""
    # Create a book with the first file
    first_book = TEST_FILES["Moby Dick; Or, The Whale - Herman Melville.epub"]
    first_content = first_book["path"].read_bytes()

    files = [("files", (first_book["path"].name, first_content, first_book["content_type"]))]
    data = {"library_id": "1"}

    create_response = await authenticated_client.post(
        "/books?library_id=1",
        files=files,
        data=data,
    )

    assert create_response.status_code == 201
    book_id = create_response.json()["id"]

    # Add the second file to the book
    second_book = TEST_FILES["Calculus Made Easy - Silvanus Thompson.pdf"]
    second_content = second_book["path"].read_bytes()

    add_files = [("data", (second_book["path"].name, second_content, second_book["content_type"]))]

    add_response = await authenticated_client.post(
        f"/books/{book_id}/files",
        files=add_files,
    )

    assert add_response.status_code == 201
    updated_book = add_response.json()

    # Verify both files have correct hashes
    assert len(updated_book["files"]) == 2

    for file_metadata in updated_book["files"]:
        assert "hash" in file_metadata

    epub_file = next(f for f in updated_book["files"] if f["path"].endswith(".epub"))
    pdf_file = next(f for f in updated_book["files"] if f["path"].endswith(".pdf"))

    assert epub_file["hash"] == first_book["hash"]
    assert pdf_file["hash"] == second_book["hash"]
