#!/usr/bin/env python3
"""Re-zip /opt/epub-translate/work into a valid EPUB.
- mimetype stored FIRST and UNCOMPRESSED (EPUB requirement)
- sets dc:language to ru and prefixes <dc:title> with "(RU) "
Usage: python 03_repackage.py
"""
import re, sys, zipfile, warnings
from pathlib import Path
from bs4 import BeautifulSoup, XMLParsedAsHTMLWarning
warnings.filterwarnings("ignore", category=XMLParsedAsHTMLWarning)

ROOT   = Path("/opt/epub-translate")
WORK   = ROOT / "work"
OUTDIR = ROOT / "output"
OUT    = OUTDIR / "Letters_from_Vladivostock_RU.epub"

def patch_opf():
    """Update language + title in the OPF package document."""
    opfs = list(WORK.rglob("*.opf"))
    if not opfs:
        print("! no .opf found — skipping metadata patch")
        return
    opf = opfs[0]
    soup = BeautifulSoup(opf.read_text(encoding="utf-8", errors="replace"), "xml")

    # dc:language -> ru
    lang = soup.find("dc:language") or soup.find("language")
    if lang:
        lang.string = "ru"
    else:
        meta = soup.find("metadata")
        if meta:
            tag = soup.new_tag("dc:language")
            tag.string = "ru"
            meta.append(tag)

    # dc:title -> prefix "(RU) "
    title = soup.find("dc:title") or soup.find("title")
    if title and title.string and not title.string.startswith("(RU)"):
        title.string = "(RU) " + title.string.strip()

    opf.write_text(str(soup), encoding="utf-8")
    print(f"patched metadata in {opf.relative_to(WORK)} (language=ru, title prefixed)")

def build_epub():
    mimetype = WORK / "mimetype"
    if not mimetype.exists():
        # EPUB must have it; create canonical value
        mimetype.write_text("application/epub+zip", encoding="utf-8")
        print("created missing mimetype file")

    OUTDIR.mkdir(parents=True, exist_ok=True)
    if OUT.exists():
        OUT.unlink()

    with zipfile.ZipFile(OUT, "w") as z:
        # 1) mimetype FIRST, STORED (no compression), no extra fields
        z.writestr("mimetype", "application/epub+zip", compress_type=zipfile.ZIP_STORED)
        # 2) everything else, deflated, preserving relative paths
        for p in sorted(WORK.rglob("*")):
            if not p.is_file() or p.name == "mimetype":
                continue
            arcname = str(p.relative_to(WORK))
            z.write(p, arcname, compress_type=zipfile.ZIP_DEFLATED)

    size_mb = OUT.stat().st_size / 1_048_576
    print(f"\nBuilt: {OUT}  ({size_mb:.2f} MB)")

def main():
    if not WORK.exists():
        sys.exit("work/ not found — run 02_translate.py first")
    patch_opf()
    build_epub()
    print("\nValidate (recommended):")
    print("  # one-off, no system install — uses a temp venv tool or downloaded jar")
    print("  java -jar epubcheck.jar", OUT)

if __name__ == "__main__":
    main()

