#!/usr/bin/env python3
"""Append a new <item> to feed.xml.

Usage:
    python3 add.py --title "..." --body-file note.html [--slug 2026-05-03-foo]
    echo "<p>html body</p>" | python3 add.py --title "..."

The body is HTML and goes inside <description><![CDATA[ ... ]]></description>.
GUID is stable based on the slug (or auto-generated date+title hash).
"""
from __future__ import annotations

import argparse
import hashlib
import re
import sys
from datetime import datetime, timezone
from pathlib import Path
from xml.sax.saxutils import escape

FEED_PATH = Path(__file__).parent / "feed.xml"
BASE_URL = "https://alex-mbp.tail948c94.ts.net"  # served by tailscale funnel from this Mac


def slugify(title: str) -> str:
    s = title.lower()
    s = re.sub(r"[^\w\s-]", "", s, flags=re.UNICODE)
    s = re.sub(r"[\s_-]+", "-", s).strip("-")
    return s[:60] or "item"


def make_slug(title: str) -> str:
    today = datetime.now(timezone.utc).strftime("%Y-%m-%d")
    return f"{today}-{slugify(title)}"


def rfc822(dt: datetime) -> str:
    # Locale-independent RFC-822 date
    months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
             "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
    days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
    return (f"{days[dt.weekday()]}, {dt.day:02d} {months[dt.month-1]} "
            f"{dt.year} {dt.strftime('%H:%M:%S')} +0000")


def build_item(title: str, body_html: str, slug: str, pub: datetime) -> str:
    guid = f"ai-fun-{slug}"
    return (
        "    <item>\n"
        f"      <title>{escape(title)}</title>\n"
        f"      <link>{BASE_URL}/{slug}</link>\n"
        f"      <guid isPermaLink=\"false\">{guid}</guid>\n"
        f"      <pubDate>{rfc822(pub)}</pubDate>\n"
        f"      <description><![CDATA[\n{body_html.strip()}\n      ]]></description>\n"
        "    </item>\n"
    )


def insert_item(feed_xml: str, item_xml: str, pub: datetime) -> str:
    # Update lastBuildDate
    feed_xml = re.sub(
        r"<lastBuildDate>[^<]*</lastBuildDate>",
        f"<lastBuildDate>{rfc822(pub)}</lastBuildDate>",
        feed_xml,
        count=1,
    )
    # Insert new item right after <lastBuildDate>...</lastBuildDate>\n
    marker = re.search(r"</lastBuildDate>\s*\n", feed_xml)
    if not marker:
        raise SystemExit("feed.xml: <lastBuildDate> not found")
    pos = marker.end()
    return feed_xml[:pos] + item_xml + feed_xml[pos:]


def main() -> int:
    p = argparse.ArgumentParser()
    p.add_argument("--title", required=True)
    p.add_argument("--body-file", help="path to HTML body; if omitted reads stdin")
    p.add_argument("--slug", help="custom slug (default: <date>-<title>)")
    args = p.parse_args()

    if args.body_file:
        body = Path(args.body_file).read_text(encoding="utf-8")
    else:
        body = sys.stdin.read()
    if not body.strip():
        raise SystemExit("empty body")

    slug = args.slug or make_slug(args.title)
    pub = datetime.now(timezone.utc)

    feed_xml = FEED_PATH.read_text(encoding="utf-8")
    item_xml = build_item(args.title, body, slug, pub)
    new_feed = insert_item(feed_xml, item_xml, pub)
    FEED_PATH.write_text(new_feed, encoding="utf-8")
    print(f"added: {slug}")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
