from __future__ import annotations

import csv
import hashlib
import json
from pathlib import Path
from zipfile import ZIP_DEFLATED, ZIP_STORED, ZipFile, ZipInfo


ROOT = Path(__file__).parent
OUTPUT = ROOT / "field-notes-with-print-pages.epub"
FIXED_TIME = (2026, 9, 20, 0, 0, 0)

PAGES = [
    ("i", "frontmatter.xhtml", "page-i", "Title page", "Front matter", False),
    ("ii", "frontmatter.xhtml", "page-ii", "Copyright and edition note", "Front matter", False),
    ("1", "chapter.xhtml", "page-1", "Chapter opening", "Body matter", False),
    ("2", "chapter.xhtml", "page-2", "Boundary inside a paragraph", "Body matter", False),
    ("3", "chapter.xhtml", "page-3", "Blank print page", "Body matter", True),
    ("4", "chapter.xhtml", "page-4", "Text resumes after the blank page", "Body matter", False),
]

MIMETYPE = "application/epub+zip"
CONTAINER = """<?xml version="1.0" encoding="UTF-8"?>
<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
  <rootfiles><rootfile full-path="EPUB/package.opf" media-type="application/oebps-package+xml"/></rootfiles>
</container>
"""


def write_entry(book: ZipFile, name: str, data: str, compression: int) -> None:
    info = ZipInfo(name, FIXED_TIME)
    info.compress_type = compression
    info.external_attr = 0o644 << 16
    book.writestr(info, data.encode("utf-8"))


def build_epub() -> None:
    frontmatter = """<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" xml:lang="en" lang="en">
<head><title>Front matter</title><link rel="stylesheet" type="text/css" href="style.css"/></head>
<body epub:type="frontmatter">
  <section epub:type="titlepage"><span id="page-i" epub:type="pagebreak" role="doc-pagebreak" aria-label="i"/><h1>Field Notes</h1><p>A controlled pagination fixture.</p></section>
  <section epub:type="copyright-page"><span id="page-ii" epub:type="pagebreak" role="doc-pagebreak" aria-label="ii"/><h2>Edition note</h2><p>Pagination follows the fixture's print source.</p></section>
</body>
</html>
"""
    chapter = """<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" xml:lang="en" lang="en">
<head><title>Chapter One</title><link rel="stylesheet" type="text/css" href="style.css"/></head>
<body epub:type="bodymatter chapter">
  <span id="page-1" epub:type="pagebreak" role="doc-pagebreak" aria-label="1"/><h1>Chapter One</h1>
  <p>The first note begins at the edge of the garden and follows the path toward the glasshouse.</p>
  <p>A printed sentence begins on the previous source page. <span id="page-2" epub:type="pagebreak" role="doc-pagebreak" aria-label="2"/>The next sentence begins on print page 2, so the marker remains inside this paragraph without forcing a screen break.</p>
  <span id="page-3" epub:type="pagebreak" role="doc-pagebreak" aria-label="3"/>
  <p><span id="page-4" epub:type="pagebreak" role="doc-pagebreak" aria-label="4"/>The source page numbered 3 was intentionally blank, so the next text starts on print page 4.</p>
</body>
</html>
"""
    nav_items = "".join(
        f'<li><a href="{file_name}#{marker}">{label}</a></li>'
        for label, file_name, marker, _, _, _ in PAGES
    )
    nav = f"""<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" xml:lang="en" lang="en">
<head><title>Navigation</title></head>
<body>
  <nav epub:type="toc" id="toc"><h1>Contents</h1><ol><li><a href="chapter.xhtml">Chapter One</a></li></ol></nav>
  <nav epub:type="page-list" hidden="hidden"><h2>Print pages</h2><ol>{nav_items}</ol></nav>
</body>
</html>
"""
    package = """<?xml version="1.0" encoding="UTF-8"?>
<package xmlns="http://www.idpf.org/2007/opf" version="3.0" unique-identifier="pub-id" xml:lang="en">
  <metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
    <dc:identifier id="pub-id">urn:uuid:cc016641-150d-5cff-b841-881738723c06</dc:identifier>
    <dc:title>Field Notes with Print Pages</dc:title>
    <dc:creator>BookTranslator Test Fixture</dc:creator>
    <dc:language>en</dc:language>
    <dc:rights>CC0 1.0 Universal</dc:rights>
    <meta property="pageBreakSource">urn:uuid:5b247d07-a036-590d-af5b-252c5cb4b980</meta>
    <meta property="schema:accessibilityFeature">pageBreakMarkers</meta>
    <meta property="schema:accessibilityFeature">pageNavigation</meta>
    <meta property="dcterms:modified">2026-09-20T00:00:00Z</meta>
  </metadata>
  <manifest>
    <item id="nav" href="nav.xhtml" media-type="application/xhtml+xml" properties="nav"/>
    <item id="front" href="frontmatter.xhtml" media-type="application/xhtml+xml"/>
    <item id="chapter" href="chapter.xhtml" media-type="application/xhtml+xml"/>
    <item id="css" href="style.css" media-type="text/css"/>
  </manifest>
  <spine><itemref idref="front"/><itemref idref="chapter"/></spine>
</package>
"""
    style = "body { font-family: serif; line-height: 1.55; margin: 5%; } [role='doc-pagebreak'] { display: inline; }"
    with ZipFile(OUTPUT, "w") as book:
        write_entry(book, "mimetype", MIMETYPE, ZIP_STORED)
        write_entry(book, "META-INF/container.xml", CONTAINER, ZIP_DEFLATED)
        write_entry(book, "EPUB/package.opf", package, ZIP_DEFLATED)
        write_entry(book, "EPUB/nav.xhtml", nav, ZIP_DEFLATED)
        write_entry(book, "EPUB/frontmatter.xhtml", frontmatter, ZIP_DEFLATED)
        write_entry(book, "EPUB/chapter.xhtml", chapter, ZIP_DEFLATED)
        write_entry(book, "EPUB/style.css", style, ZIP_DEFLATED)


def write_inventory() -> None:
    with (ROOT / "page-inventory.csv").open("w", newline="", encoding="utf-8") as handle:
        writer = csv.writer(handle, lineterminator="\n")
        writer.writerow(["print_label", "content_file", "marker_id", "source_content", "section", "blank_page"])
        writer.writerows(PAGES)


def main() -> None:
    write_inventory()
    build_epub()
    digest = hashlib.sha256(OUTPUT.read_bytes()).hexdigest()
    manifest = {
        "title": "Field Notes with Print Pages",
        "license": "CC0-1.0",
        "generated": "2026-09-20",
        "pages": len(PAGES),
        "epub_sha256": digest,
        "notes": "Synthetic publishing fixture; not a BookTranslator product output or reader benchmark.",
    }
    (ROOT / "fixture-manifest.json").write_text(json.dumps(manifest, indent=2) + "\n", encoding="utf-8")
    print(json.dumps(manifest, indent=2))


if __name__ == "__main__":
    main()
