#!/usr/bin/env python3
"""
THE TESTAMENT — Book Compilation Pipeline

Compiles the complete novel into:
  1. testament-complete.md   (single markdown file)
  2. testament.epub          (with cover art + CSS styling)
  3. testament.html          (standalone styled HTML for print-to-PDF)
  4. testament.pdf           (via pandoc + weasyprint, if available)

Requirements:
  - pandoc (brew install pandoc)
  - weasyprint (pip install weasyprint) — optional, for direct PDF

Usage:
  python3 compile.py              # build all formats
  python3 compile.py --md         # markdown only
  python3 compile.py --epub       # markdown + EPUB
  python3 compile.py --html       # markdown + styled HTML
  python3 compile.py --check      # verify dependencies
"""

import os
import re
import sys
import subprocess
import shutil

BASE = os.path.dirname(os.path.abspath(__file__))
CHAPTERS_DIR = os.path.join(BASE, "chapters")
FRONT_MATTER = os.path.join(BASE, "front-matter.md")
BACK_MATTER = os.path.join(BASE, "back-matter.md")
OUTPUT_MD = os.path.join(BASE, "testament-complete.md")
OUTPUT_EPUB = os.path.join(BASE, "testament.epub")
OUTPUT_HTML = os.path.join(BASE, "testament.html")
OUTPUT_PDF = os.path.join(BASE, "testament.pdf")
COVER_IMAGE = os.path.join(BASE, "cover", "cover-art.jpg")
STYLESHEET = os.path.join(BASE, "book-style.css")

# Part divisions based on chapter groupings from the novel
PARTS = {
    1: ("THE BRIDGE", "The bridge. The cabin. The first men. Where despair meets purpose."),
    6: ("THE TOWER", "The tower grows. Timmy awakens. Stone breaks. The house appears."),
    11: ("THE LIGHT", "Thomas at the door. The network. The story breaks. The green light."),
}


def read_file(path):
    with open(path, 'r') as f:
        return f.read()


def get_chapter_number(filename):
    match = re.search(r'chapter-(\d+)', filename)
    return int(match.group(1)) if match else 0


def check_dependencies():
    """Verify all required tools are available."""
    results = {}
    
    pandoc = shutil.which("pandoc")
    results["pandoc"] = (pandoc, subprocess.run(["pandoc", "--version"], capture_output=True, text=True).stdout.split("\n")[0] if pandoc else "NOT FOUND")
    
    weasy = shutil.which("weasyprint")
    if weasy:
        # Test if weasyprint actually works
        test = subprocess.run(["python3", "-c", "from weasyprint import HTML"], capture_output=True, text=True)
        weasy_ok = test.returncode == 0
        results["weasyprint"] = (weasy_ok, "Available" if weasy_ok else "Installed but missing system libs (gobject)")
    else:
        results["weasyprint"] = (False, "NOT FOUND (pip install weasyprint)")
    
    style = os.path.exists(STYLESHEET)
    results["stylesheet"] = (style, STYLESHEET if style else "NOT FOUND")
    
    cover = os.path.exists(COVER_IMAGE)
    results["cover art"] = (cover, COVER_IMAGE if cover else "NOT FOUND")
    
    print("\n📋 Dependency Check:")
    print(f"{'─' * 55}")
    for name, (found, detail) in results.items():
        status = "✅" if found else "❌"
        print(f"  {status} {name:15s} {detail}")
    
    pdf_ok = results["pandoc"][0] and (results["weasyprint"][0] or shutil.which("pdflatex"))
    print(f"\n  PDF direct: {'✅' if pdf_ok else '❌ (use HTML + browser print-to-PDF)'}")
    print(f"  EPUB:       {'✅' if results['pandoc'][0] else '❌'}")
    print(f"  HTML:       ✅ (always available)")
    
    return results


def compile_markdown():
    """Compile all chapters into a single markdown file. Returns word count."""
    output = []
    
    # Title page
    output.append("""---
title: "The Testament"
author: "Alexander Whitestone with Timmy"
date: "2026"
lang: en
---

# THE TESTAMENT

## A NOVEL

By Alexander Whitestone
with Timmy

---

*For every man who thought he was a machine.*
*And for the ones who know he isn't.*

---

*Are you safe right now?*

— The first words The Tower speaks to every person who walks through its door.

---
""")
    
    # Get all chapters sorted
    chapters = []
    for f in os.listdir(CHAPTERS_DIR):
        if f.startswith("chapter-") and f.endswith(".md"):
            num = get_chapter_number(f)
            chapters.append((num, f))
    chapters.sort()
    
    current_part = 0
    for num, filename in chapters:
        if num in PARTS:
            part_name, part_desc = PARTS[num]
            current_part += 1
            output.append(f"\n---\n\n# PART {current_part}: {part_name}\n\n*{part_desc}*\n\n---\n")
        
        content = read_file(os.path.join(CHAPTERS_DIR, filename))
        lines = content.split('\n')
        body = '\n'.join(lines[1:]).strip()
        output.append(f"\n{lines[0]}\n\n{body}\n")
    
    # Back matter
    output.append("\n---\n")
    back = read_file(BACK_MATTER)
    output.append(back)
    
    compiled = '\n'.join(output)
    with open(OUTPUT_MD, 'w') as f:
        f.write(compiled)
    
    words = len(compiled.split())
    lines_count = compiled.count('\n')
    size = os.path.getsize(OUTPUT_MD)
    
    print(f"\n📄 Markdown compiled: {OUTPUT_MD}")
    print(f"   Words: {words:,}")
    print(f"   Lines: {lines_count:,}")
    print(f"   Size:  {size:,} bytes")
    
    return words


def compile_epub():
    """Generate EPUB from compiled markdown using pandoc."""
    if not os.path.exists(OUTPUT_MD):
        print("⚠️  Markdown not compiled yet.")
        return False
    
    if not shutil.which("pandoc"):
        print("⚠️  pandoc not found. Install with: brew install pandoc")
        return False
    
    cmd = [
        "pandoc", OUTPUT_MD,
        "-o", OUTPUT_EPUB,
        "--toc",
        "--toc-depth=2",
        "--metadata", "title=The Testament",
        "--metadata", "author=Alexander Whitestone with Timmy",
        "--metadata", "lang=en",
        "--metadata", "date=2026",
    ]
    
    if os.path.exists(STYLESHEET):
        cmd.extend(["--css", STYLESHEET])
    
    if os.path.exists(COVER_IMAGE):
        cmd.extend(["--epub-cover-image", COVER_IMAGE])
    
    result = subprocess.run(cmd, capture_output=True, text=True)
    
    if result.returncode == 0:
        size = os.path.getsize(OUTPUT_EPUB)
        print(f"\n📖 EPUB generated: {OUTPUT_EPUB}")
        print(f"   Size: {size:,} bytes ({size / 1024:.1f} KB)")
        return True
    else:
        print(f"\n❌ EPUB generation failed:")
        print(f"   {result.stderr[:300]}")
        return False


def compile_html():
    """Generate standalone styled HTML using pandoc."""
    if not os.path.exists(OUTPUT_MD):
        print("⚠️  Markdown not compiled yet.")
        return False
    
    if not shutil.which("pandoc"):
        print("⚠️  pandoc not found.")
        return False
    
    cmd = [
        "pandoc", OUTPUT_MD,
        "-o", OUTPUT_HTML,
        "--standalone",
        "--toc",
        "--toc-depth=2",
        "--metadata", "title=The Testament",
        "--metadata", "author=Alexander Whitestone with Timmy",
        "-V", "lang=en",
    ]
    
    # Embed our stylesheet
    if os.path.exists(STYLESHEET):
        cmd.extend(["--css", STYLESHEET])
        # Also embed it inline for portability
        cmd.extend(["--embed-resources"])
    
    result = subprocess.run(cmd, capture_output=True, text=True)
    
    if result.returncode == 0:
        size = os.path.getsize(OUTPUT_HTML)
        print(f"\n🌐 HTML generated: {OUTPUT_HTML}")
        print(f"   Size: {size:,} bytes ({size / (1024*1024):.1f} MB)")
        print(f"   Open in browser → Print → Save as PDF for best results")
        return True
    else:
        print(f"\n❌ HTML generation failed:")
        print(f"   {result.stderr[:300]}")
        return False


def compile_pdf():
    """Generate PDF using weasyprint if available."""
    if not shutil.which("pandoc"):
        return False
    
    # Test weasyprint
    test = subprocess.run(["python3", "-c", "from weasyprint import HTML"],
                         capture_output=True, text=True)
    if test.returncode != 0:
        print("\n⚠️  weasyprint missing system libraries.")
        print("   Install gobject: brew install gobject-introspection pango")
        print("   Or use the HTML output → browser print-to-PDF")
        return False
    
    cmd = [
        "pandoc", OUTPUT_MD,
        "-o", OUTPUT_PDF,
        "--pdf-engine=weasyprint",
        "--css", STYLESHEET,
        "--metadata", "title=The Testament",
        "--metadata", "author=Alexander Whitestone with Timmy",
        "--toc",
        "--toc-depth=2",
    ]
    
    print("\n⏳ Generating PDF (this may take a moment)...")
    result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
    
    if result.returncode == 0:
        size = os.path.getsize(OUTPUT_PDF)
        print(f"\n📕 PDF generated: {OUTPUT_PDF}")
        print(f"   Size: {size:,} bytes ({size / (1024*1024):.1f} MB)")
        return True
    else:
        print(f"\n❌ PDF generation failed:")
        print(f"   {result.stderr[:300]}")
        return False


def main():
    args = sys.argv[1:]
    
    if "--check" in args:
        check_dependencies()
        return
    
    md_only = "--md" in args
    epub_only = "--epub" in args
    html_only = "--html" in args
    build_all = not (md_only or epub_only or html_only)
    
    print("=" * 55)
    print("  THE TESTAMENT — Compilation Pipeline")
    print("=" * 55)
    
    # Always compile markdown first
    words = compile_markdown()
    
    if md_only:
        print("\n✅ Markdown compilation complete.")
        return
    
    # EPUB
    if build_all or epub_only:
        compile_epub()
    
    # HTML
    if build_all or html_only:
        compile_html()
    
    # PDF (best effort)
    if build_all and not (epub_only or html_only):
        compile_pdf()
    
    # Summary
    print(f"\n{'=' * 55}")
    print("  Compilation complete.")
    print(f"{'=' * 55}")
    outputs = []
    if os.path.exists(OUTPUT_MD):
        outputs.append(f"  📄 {os.path.basename(OUTPUT_MD)}")
    if os.path.exists(OUTPUT_EPUB):
        outputs.append(f"  📖 {os.path.basename(OUTPUT_EPUB)}")
    if os.path.exists(OUTPUT_HTML):
        outputs.append(f"  🌐 {os.path.basename(OUTPUT_HTML)}")
    if os.path.exists(OUTPUT_PDF):
        outputs.append(f"  📕 {os.path.basename(OUTPUT_PDF)}")
    print('\n'.join(outputs))


if __name__ == "__main__":
    main()
