import { Request } from '../http/Request.js';
const lowerCaseHeaders = (headers) => {
    if (!headers)
        return {};
    const out = {};
    for (const [k, v] of Object.entries(headers))
        out[k.toLowerCase()] = v;
    return out;
};
const isError = (v) => v instanceof Error;
export const TestHttp = Object.freeze({
    createRequest(input = {}) {
        const nodeReq = {
            method: input.method ?? 'GET',
            url: input.path ?? '/',
            headers: lowerCaseHeaders(input.headers),
        };
        const req = Request.create(nodeReq);
        if (input.body !== undefined)
            req.setBody(input.body);
        if (input.params !== undefined)
            req.setParams(input.params);
        const validated = input.validated;
        if (validated !== undefined && validated !== null && !isError(validated)) {
            req.validated = validated;
        }
        if (input.context !== undefined)
            req.context = input.context;
        return req;
    },
    createValidatedRequest(input) {
        const req = this.createRequest({
            ...input,
            validated: input.validated,
        });
        return req;
    },
    createResponseRecorder() {
        let statusCodeValue = 200;
        let bodyText = '';
        let jsonBody;
        const headers = {};
        const raw = {
            statusCode: statusCodeValue,
            writableEnded: false,
            setHeader: (name, value) => {
                headers[name] = value;
            },
            end: (data) => {
                raw.writableEnded = true;
                if (data === undefined)
                    return;
                bodyText += Buffer.isBuffer(data) ? data.toString('utf8') : String(data);
            },
        };
        const res = {
            locals: {},
            status: (code) => res.setStatus(code),
            setStatus: (code) => {
                statusCodeValue = code;
                raw.statusCode = code;
                return res;
            },
            getStatus: () => statusCodeValue,
            get statusCode() {
                return statusCodeValue;
            },
            setHeader: (name, value) => {
                headers[name] = value;
                return res;
            },
            getHeader: (name) => headers[name],
            json: (data) => {
                jsonBody = data;
                bodyText = JSON.stringify(data);
            },
            text: (text) => {
                bodyText = text;
            },
            html: (html) => {
                bodyText = html;
            },
            send: (data) => {
                bodyText = Buffer.isBuffer(data) ? data.toString('utf8') : String(data);
            },
            redirect: (_url, code = 302) => {
                statusCodeValue = code;
            },
            getRaw: () => raw,
            getBodyText: () => bodyText,
            getJson: () => jsonBody,
            getHeaders: () => ({ ...headers }),
        };
        return res;
    },
});
