#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.11"
# dependencies = [
#   "jinja2",
# ]
# ///
"""
Convert a markdown file to an HTML page using pandoc + a Jinja2 template.

Pandoc handles the markdown → HTML conversion (so anything pandoc supports
just works: tables, footnotes, links, etc). The resulting HTML fragment is
wrapped in `md2html_template.html.j2` living next to this script.

Optional YAML frontmatter in the source file is passed to the template as
variables (`title`, `date`, ...). If no frontmatter or no title, the file
stem is used as the title.

Usage:
    uv run _svsg/md2html.py blogroll/blogroll.md
    uv run _svsg/md2html.py path/to/file.md --out custom/output.html

Output defaults to index.html in the same directory as the source.

Requires `pandoc` on PATH.
"""

from __future__ import annotations

import argparse
import shutil
import subprocess
import sys
from pathlib import Path

from jinja2 import Environment, FileSystemLoader

ROOT = Path(__file__).resolve().parent
TEMPLATE_NAME = "md2html_template.html.j2"


def parse_frontmatter(text: str) -> tuple[dict, str]:
    """Extract a minimal YAML-ish frontmatter block from the top of the file."""
    if not text.startswith("---"):
        return {}, text
    end = text.find("\n---", 3)
    if end == -1:
        return {}, text
    fm_text = text[3:end]
    body = text[end + 4:].lstrip("\n")
    data: dict = {}
    for raw in fm_text.splitlines():
        line = raw.strip()
        if not line or ":" not in line:
            continue
        key, _, val = line.partition(":")
        data[key.strip()] = val.strip().strip('"').strip("'")
    return data, body


def run_pandoc(markdown: str) -> str:
    result = subprocess.run(
        ["pandoc", "--from=markdown", "--to=html5", "--wrap=none"],
        input=markdown,
        capture_output=True,
        text=True,
        check=True,
    )
    return result.stdout


def main() -> int:
    if shutil.which("pandoc") is None:
        print("ERROR: pandoc not found on PATH", file=sys.stderr)
        return 2

    ap = argparse.ArgumentParser(description=__doc__)
    ap.add_argument("input", type=Path, help="Markdown file to convert")
    ap.add_argument("--out", type=Path, help="Output HTML path (default: same stem, .html)")
    args = ap.parse_args()

    src: Path = args.input
    if not src.exists():
        print(f"ERROR: {src} not found", file=sys.stderr)
        return 1

    out: Path = args.out or src.parent / "index.html"

    raw = src.read_text(encoding="utf-8")
    fm, body = parse_frontmatter(raw)
    content_html = run_pandoc(body)

    env = Environment(
        loader=FileSystemLoader(str(ROOT)),
        autoescape=False,
        trim_blocks=False,
        lstrip_blocks=False,
    )
    tmpl = env.get_template(TEMPLATE_NAME)

    draft_val = str(fm.get("draft", "")).strip().lower()
    is_draft = draft_val in ("true", "yes", "1")

    author_raw = fm.get("author", "Samuel Vaiter")
    show_author = str(author_raw).strip().lower() not in ("none", "false", "no") if author_raw is not None else True

    ctx = {
        "title": fm.get("title") or src.stem.replace("-", " ").replace("_", " "),
        "date": fm.get("date", ""),
        "content": content_html,
        **fm,
        "draft": is_draft,
        "show_author": show_author,
    }
    html = tmpl.render(**ctx)
    out.write_text(html, encoding="utf-8")

    try:
        rel = out.relative_to(ROOT)
    except ValueError:
        rel = out
    print(f"Wrote {rel}")
    return 0


if __name__ == "__main__":
    sys.exit(main())
