"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getRspackMemoryAssets = void 0;
const node_crypto_1 = __importDefault(require("node:crypto"));
const node_path_1 = require("node:path");
const node_url_1 = require("node:url");
const mime_types_1 = __importDefault(require("mime-types"));
// biome-ignore lint/suspicious/noExplicitAny: _
function etag(buf) {
    const hash = node_crypto_1.default.createHash("sha256").update(buf).digest("hex");
    const etag = hash;
    return etag;
}
function createPublicPathGetter(compiler) {
    const raw = compiler.options.output.publicPath || "/";
    if (typeof raw === "function") {
        return (compilation) => compilation ? compilation.getPath(raw) : raw({ hash: "XXXX" }, undefined);
    }
    if (/\[(hash|fullhash)[:\]]/.test(raw)) {
        return (compilation) => compilation ? compilation.getPath(raw) : `${raw.replace(/\/$/, "")}/`;
    }
    return () => `${raw.replace(/\/$/, "")}/`;
}
function getRspackMemoryAssets(compiler, rdm) {
    const getPublicPath = createPublicPathGetter(compiler);
    return (req, res, next) => {
        const { method, url } = req;
        if (method !== "GET") {
            return next();
        }
        // css hmr will append query string, so here need to remove query string
        // @ts-expect-error
        const path = (0, node_url_1.parse)(url).pathname;
        const publicPath = getPublicPath(compiler._lastCompilation);
        // asset name is not start with /, so path need to slice 1
        // @ts-expect-error
        const filename = path.startsWith(publicPath)
            ? // @ts-expect-error
                path.slice(publicPath.length)
            : // @ts-expect-error
                path.slice(1);
        const buffer = compiler._lastCompilation?.getAsset(filename) ??
            (() => {
                const { index } = rdm.context.options;
                const indexValue = typeof index === "undefined" || typeof index === "boolean"
                    ? "index.html"
                    : index;
                return compiler._lastCompilation?.getAsset(filename + indexValue);
            })();
        if (!buffer) {
            return next();
        }
        let contentType;
        if (filename === "") {
            contentType = "text/html; charset=utf-8";
        }
        else {
            contentType =
                // @ts-expect-error
                mime_types_1.default.contentType((0, node_path_1.extname)(path)) || "text/plain; charset=utf-8";
        }
        const calcEtag = etag(buffer);
        const oldEtag = req.headers["if-none-match"];
        res.setHeader("Content-Type", contentType);
        res.setHeader("ETag", calcEtag);
        if (calcEtag === oldEtag) {
            res.status(304).send();
        }
        else {
            res.send(buffer);
        }
    };
}
exports.getRspackMemoryAssets = getRspackMemoryAssets;
