import { Router } from "express";
import { badRequest } from "../errors.js";
import { fetchWebsiteIcon, parsePublicHttpUrl, resolveWebsiteMetadata, } from "../services/website-metadata.js";
import { assertBoard } from "./authz.js";
function parseInspectableUrl(value) {
    if (typeof value !== "string" || !value.trim()) {
        throw badRequest("Missing url");
    }
    try {
        return parsePublicHttpUrl(value, {}).href;
    }
    catch (error) {
        const message = error instanceof Error ? error.message : "Invalid URL";
        throw badRequest(message);
    }
}
function isInspectableUrlError(error) {
    if (!(error instanceof Error))
        return false;
    return error.message === "Only http and https URLs can be inspected"
        || error.message === "Private network URLs cannot be inspected"
        || error.message === "Website metadata redirect limit exceeded";
}
export function websiteMetadataRoutes(options = {}) {
    const router = Router();
    const resolveMetadata = options.resolveWebsiteMetadata ?? ((url) => resolveWebsiteMetadata(url, options.urlOptions));
    const fetchIcon = options.fetchWebsiteIcon ?? ((url) => fetchWebsiteIcon(url, options.urlOptions));
    router.get("/website-metadata", async (req, res) => {
        assertBoard(req);
        const targetUrl = parseInspectableUrl(req.query.url);
        let metadata;
        try {
            metadata = await resolveMetadata(targetUrl);
        }
        catch (error) {
            if (isInspectableUrlError(error))
                throw badRequest(error.message);
            throw error;
        }
        const iconUrl = metadata.iconUrl
            ? `/api/website-metadata/icon?url=${encodeURIComponent(metadata.iconUrl)}`
            : null;
        res.json({ ...metadata, iconUrl });
    });
    router.get("/website-metadata/icon", async (req, res) => {
        assertBoard(req);
        const iconUrl = parseInspectableUrl(req.query.url);
        let icon;
        try {
            icon = await fetchIcon(iconUrl);
        }
        catch (error) {
            if (isInspectableUrlError(error))
                throw badRequest(error.message);
            throw error;
        }
        if (!icon) {
            res.status(404).json({ error: "Website icon not found" });
            return;
        }
        res.setHeader("content-type", icon.contentType);
        res.setHeader("cache-control", "public, max-age=86400");
        res.send(icon.body);
    });
    return router;
}
//# sourceMappingURL=website-metadata.js.map