#!/usr/bin/env python3
"""Embed a cover image into an EPUB file by patching the ZIP directly.

Usage: python3 embed_cover_epub.py <epub_path> <cover_jpg_path>

- Unzips EPUB to tempdir
- Copies cover.jpg into archive root
- Patches content.opf: adds cover-image item to manifest + meta name="cover"
- Repacks with mimetype first (STORED, uncompressed per EPUB spec)
- Preserves file ownership from original
- Creates .backup.epub of original if none exists
"""
import zipfile, shutil, os, re, sys, tempfile


def embed_cover(epub_path: str, cover_path: str) -> bool:
    if not os.path.exists(epub_path):
        print(f"❌ EPUB not found: {epub_path}")
        return False
    if not os.path.exists(cover_path):
        print(f"❌ Cover not found: {cover_path}")
        return False

    # Verify cover is a real image
    img_type = os.popen(f"file '{cover_path}'").read()
    if "GIF" in img_type and "1 x 1" in img_type:
        print(f"❌ Cover is a 1×1 GIF placeholder — refusing to embed")
        return False
    if "JPEG" not in img_type and "PNG" not in img_type:
        print(f"⚠️  Cover is not JPEG/PNG: {img_type.strip()}")

    # Backup
    backup = epub_path.replace(".epub", ".backup.epub")
    if not os.path.exists(backup):
        shutil.copy2(epub_path, backup)
        print(f"📦 Backup: {os.path.basename(backup)}")

    with tempfile.TemporaryDirectory() as tmpdir:
        # Extract EPUB
        with zipfile.ZipFile(epub_path, 'r') as zf:
            zf.extractall(tmpdir)

        # Copy cover into archive root
        cover_dest = os.path.join(tmpdir, "cover.jpg")
        shutil.copy2(cover_path, cover_dest)

        # Find content.opf
        opf_path = None
        for root, dirs, files in os.walk(tmpdir):
            for f in files:
                if f.endswith('.opf'):
                    opf_path = os.path.join(root, f)
                    break
        if not opf_path:
            print("❌ No OPF found in EPUB")
            return False

        print(f"📄 Editing: {os.path.basename(opf_path)}")

        with open(opf_path, 'r') as f:
            opf = f.read()

        # Replace existing cover or add new one
        cover_item_match = re.search(
            r'<item[^>]*id="[^"]*cover[^"]*"[^>]*/?>', opf, re.IGNORECASE
        )
        new_item = '<item id="cover-image" href="cover.jpg" media-type="image/jpeg" properties="cover-image"/>'

        if cover_item_match:
            opf = opf.replace(cover_item_match.group(), new_item)
            print("  ♻️  Cover item replaced")
        else:
            opf = opf.replace('</manifest>', f'  {new_item}\n  </manifest>', 1)
            print("  ✨ Cover item added")

        # Ensure <meta name="cover"> exists
        if '<meta name="cover"' not in opf:
            opf = opf.replace(
                '<metadata',
                '<metadata>\n    <meta name="cover" content="cover-image"/>',
                1,
            )
            print("  ✨ <meta name=\"cover\"> added")

        # Write modified OPF back
        with open(opf_path, 'w') as f:
            f.write(opf)

        # Preserve ownership
        orig_stat = os.stat(epub_path)

        # Remove old EPUB
        os.remove(epub_path)

        # Repack: mimetype MUST be first, STORED (uncompressed)
        with zipfile.ZipFile(epub_path, 'w', zipfile.ZIP_DEFLATED) as zout:
            mimetype_path = os.path.join(tmpdir, "mimetype")
            if os.path.exists(mimetype_path):
                zout.write(mimetype_path, "mimetype", zipfile.ZIP_STORED)
            else:
                zout.writestr("mimetype", "application/epub+zip", zipfile.ZIP_STORED)

            for root, dirs, files in os.walk(tmpdir):
                for f in files:
                    full = os.path.join(root, f)
                    arcname = os.path.relpath(full, tmpdir)
                    if arcname == "mimetype":
                        continue
                    zout.write(full, arcname, zipfile.ZIP_DEFLATED)

        # Restore ownership
        os.chown(epub_path, orig_stat.st_uid, orig_stat.st_gid)

        print(f"✅ Cover embedded: {os.path.basename(epub_path)}")
        return True


if __name__ == "__main__":
    if len(sys.argv) != 3:
        print(f"Usage: {sys.argv[0]} <epub_path> <cover_jpg_path>")
        sys.exit(1)
    success = embed_cover(sys.argv[1], sys.argv[2])
    sys.exit(0 if success else 1)
