import { parseHTML } from "linkedom";
import { createLogger } from "../../../logger.js";
const log = createLogger("search");
function textOf(el) {
  if (!el) return "";
  return (el.textContent ?? "").trim();
}
function toIso(raw) {
  if (!raw) return void 0;
  const d = new Date(raw);
  if (isNaN(d.getTime())) return void 0;
  return d.toISOString();
}
function parseRss(doc, feedUrl) {
  const channel = doc.querySelector("rss > channel") ?? doc.querySelector("channel");
  if (!channel) return null;
  const items = Array.from(channel.querySelectorAll("item"));
  if (items.length === 0) return null;
  const feedTitle = textOf(channel.querySelector("title")) || feedUrl;
  const parsed = [];
  for (const item of items) {
    const title = textOf(item.querySelector("title"));
    const link = textOf(item.querySelector("rsslink"));
    const description = textOf(item.querySelector("description"));
    const guid = textOf(item.querySelector("guid")) || link;
    const pubDate = textOf(item.querySelector("pubDate"));
    if (!title || !link) continue;
    const entry = {
      guid: guid || link,
      title,
      link,
      summary: description
    };
    const iso = toIso(pubDate);
    if (iso) entry.publishedDate = iso;
    parsed.push(entry);
  }
  return { feedUrl, feedTitle, items: parsed };
}
function parseAtom(doc, feedUrl) {
  const feed = doc.querySelector("feed");
  if (!feed) return null;
  const entries = Array.from(feed.querySelectorAll("entry"));
  if (entries.length === 0) return null;
  const feedTitle = textOf(feed.querySelector("title")) || feedUrl;
  const parsed = [];
  for (const entry of entries) {
    const title = textOf(entry.querySelector("title"));
    const linkEl = Array.from(entry.querySelectorAll("link")).find(
      (l) => (l.getAttribute("rel") ?? "alternate") === "alternate"
    ) ?? entry.querySelector("link");
    const link = linkEl?.getAttribute("href") ?? "";
    const summaryEl = entry.querySelector("summary");
    const contentEl = entry.querySelector("content");
    const summary = textOf(summaryEl) || textOf(contentEl);
    const id = textOf(entry.querySelector("id")) || link;
    const published = textOf(entry.querySelector("published")) || textOf(entry.querySelector("updated"));
    if (!title || !link) continue;
    const item = {
      guid: id || link,
      title,
      link,
      summary
    };
    const iso = toIso(published);
    if (iso) item.publishedDate = iso;
    parsed.push(item);
  }
  return { feedUrl, feedTitle, items: parsed };
}
function rewriteRssLinks(xml) {
  return xml.replace(/<link>([\s\S]*?)<\/link>/g, "<rsslink>$1</rsslink>");
}
function parseFeed(xml, feedUrl) {
  if (!xml || xml.trim().length === 0) return null;
  const prepared = rewriteRssLinks(xml);
  let doc;
  try {
    ({ document: doc } = parseHTML(prepared));
  } catch (err) {
    log.warn("feed XML parse failed", {
      feedUrl,
      error: err instanceof Error ? err.message : String(err)
    });
    return null;
  }
  const rss = parseRss(doc, feedUrl);
  if (rss) return rss;
  const atom = parseAtom(doc, feedUrl);
  if (atom) return atom;
  if (doc.querySelector("rss") || doc.querySelector("channel") || doc.querySelector("feed")) {
    const isAtom = !!doc.querySelector("feed");
    return {
      feedUrl,
      feedTitle: textOf(doc.querySelector(isAtom ? "feed > title" : "channel > title")) || feedUrl,
      items: []
    };
  }
  return null;
}
export {
  parseFeed
};
//# sourceMappingURL=feed-parser.js.map