<?php
/**
 * ipity.foo — Mr T news feed
 *
 *   /feed.php                   RSS 2.0 (subscribe to this)
 *   /feed.php?format=json       JSON, used by news.html and the homepage
 *   /feed.php?limit=20          cap the number of items (1–100, default 50)
 *   php feed.php --refresh      CLI: force an upstream refresh (e.g. from cron)
 *
 * Items are cached in ./cache (falls back to the system temp dir) and
 * refreshed from upstream at most every 30 minutes.
 */
require __DIR__ . '/includes/mrt-news.php';

$cli    = PHP_SAPI === 'cli';
$data   = mrt_news_get($cli && in_array('--refresh', $argv ?? [], true));
$format = !$cli && ($_GET['format'] ?? '') === 'json' ? 'json' : 'rss';
$limit  = max(1, min(100, (int) ($_GET['limit'] ?? 50)));
$items  = array_slice($data['items'], 0, $limit);

$title       = 'Mr T News — ipity.foo';
$description = 'The latest news, interviews and chatter about Mr T (Laurence Tureaud), gathered from around the web every 30 minutes.';
$pageUrl     = MRT_SITE_URL . '/news.html';
$feedUrl     = MRT_SITE_URL . '/feed.php';
$updated     = (int) ($data['checked_at'] ?? time());

if ($format === 'json') {
    $body = json_encode([
        'title'    => $title,
        'feed_url' => $feedUrl,
        'updated'  => gmdate('c', $updated),
        'items'    => array_map(function ($it) {
            return [
                'title'     => $it['title'],
                'link'      => $it['link'],
                'summary'   => $it['summary'],
                'publisher' => $it['publisher'],
                'published' => gmdate('c', $it['published']),
                'type'      => $it['type'],
                'via'       => $it['origin_name'],
            ];
        }, $items),
        'sources'  => $data['sources'] ?? [],
    ], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
    $type = 'application/json';
} else {
    $x = new XMLWriter();
    $x->openMemory();
    $x->setIndent(true);
    $x->startDocument('1.0', 'UTF-8');
    $x->startElement('rss');
    $x->writeAttribute('version', '2.0');
    $x->writeAttribute('xmlns:atom', 'http://www.w3.org/2005/Atom');
    $x->startElement('channel');
    $x->writeElement('title', $title);
    $x->writeElement('link', $pageUrl);
    $x->startElement('atom:link');
    $x->writeAttribute('href', $feedUrl);
    $x->writeAttribute('rel', 'self');
    $x->writeAttribute('type', 'application/rss+xml');
    $x->endElement();
    $x->writeElement('description', $description);
    $x->writeElement('language', 'en-gb');
    $x->writeElement('lastBuildDate', gmdate(DATE_RSS, $updated));
    $x->writeElement('ttl', '30');
    $x->writeElement('generator', 'ipity.foo news aggregator');
    $x->startElement('image');
    $x->writeElement('url', MRT_SITE_URL . '/mohawk-icon.png');
    $x->writeElement('title', $title);
    $x->writeElement('link', $pageUrl);
    $x->endElement();

    foreach ($items as $it) {
        $x->startElement('item');
        $x->writeElement('title', $it['title']);
        $x->writeElement('link', $it['link']);
        $x->startElement('guid');
        $x->writeAttribute('isPermaLink', 'false');
        $x->text('ipity.foo:' . $it['id']);
        $x->endElement();
        $x->writeElement('pubDate', gmdate(DATE_RSS, $it['published']));
        $x->writeElement('description', $it['summary'] !== '' ? $it['summary'] . ' — via ' . $it['publisher'] : 'Via ' . $it['publisher']);
        $x->writeElement('category', $it['type']);
        if ($it['source_url'] !== '') {
            $x->startElement('source');
            $x->writeAttribute('url', $it['source_url']);
            $x->text($it['publisher']);
            $x->endElement();
        }
        $x->endElement();
    }

    $x->endElement(); // channel
    $x->endElement(); // rss
    $x->endDocument();
    $body = $x->outputMemory();
    $type = 'application/rss+xml';
}

if ($cli) {
    echo $body;
    return;
}

$etag = '"' . md5($body) . '"';
header('Content-Type: ' . $type . '; charset=UTF-8');
header('Cache-Control: public, max-age=600');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $updated) . ' GMT');
header('ETag: ' . $etag);
header('X-Content-Type-Options: nosniff');
if (trim($_SERVER['HTTP_IF_NONE_MATCH'] ?? '') === $etag) {
    http_response_code(304);
    return;
}
echo $body;
