import { isDocument, isFormData, isNullish, isObject, isString, } from '../utils/type-utils';
import { formDataToQuery } from '../utils/request-utils';
import { configs } from './configs';
function _tryReadXHRBody({ body, url, }) {
    if (isNullish(body)) {
        return null;
    }
    if (isString(body)) {
        return body;
    }
    if (isDocument(body)) {
        return body.textContent;
    }
    if (isFormData(body)) {
        return formDataToQuery(body);
    }
    if (isObject(body)) {
        try {
            return JSON.stringify(body);
        }
        catch (_a) {
            return '[XHR] Failed to stringify response object';
        }
    }
    return `[XHR] Cannot read body of type ${toString.call(body)}`;
}
function _isWithinPayloadLimit(payload) {
    try {
        if (typeof Blob !== 'undefined') {
            return new Blob([payload]).size <= configs.maxCapturingHttpPayloadSize;
        }
    }
    catch (_a) {
        // ignore and fallback to string length
    }
    return payload.length <= configs.maxCapturingHttpPayloadSize;
}
// Only patch XHR in environments where it exists (avoid SSR/Node)
if (typeof XMLHttpRequest !== 'undefined') {
    (function (xhr) {
        // Idempotency guard: avoid double-patching
        // @ts-ignore
        if (xhr.__mp_session_recorder_patched__) {
            return;
        }
        // @ts-ignore
        ;
        xhr.__mp_session_recorder_patched__ = true;
        const originalOpen = xhr.open;
        xhr.open = function (method, url, async = true, username, password) {
            const xhr = this;
            const networkRequest = {};
            // @ts-ignore
            const requestHeaders = {};
            const originalSetRequestHeader = xhr.setRequestHeader.bind(xhr);
            xhr.setRequestHeader = (header, value) => {
                requestHeaders[header] = value;
                return originalSetRequestHeader(header, value);
            };
            if (configs.recordRequestHeaders) {
                networkRequest.requestHeaders = requestHeaders;
            }
            const originalSend = xhr.send.bind(xhr);
            xhr.send = (body) => {
                if (configs.shouldRecordBody) {
                    const requestBody = _tryReadXHRBody({ body, url });
                    if ((requestBody === null || requestBody === void 0 ? void 0 : requestBody.length)
                        && _isWithinPayloadLimit(requestBody)) {
                        networkRequest.requestBody = requestBody;
                    }
                }
                return originalSend(body);
            };
            xhr.addEventListener('readystatechange', () => {
                if (xhr.readyState !== xhr.DONE) {
                    return;
                }
                // @ts-ignore
                const responseHeaders = {};
                const rawHeaders = xhr.getAllResponseHeaders();
                const headers = rawHeaders.trim().split(/[\r\n]+/);
                headers.forEach((line) => {
                    const parts = line.split(': ');
                    const header = parts.shift();
                    const value = parts.join(': ');
                    if (header) {
                        responseHeaders[header] = value;
                    }
                });
                if (configs.recordResponseHeaders) {
                    networkRequest.responseHeaders = responseHeaders;
                }
                if (configs.shouldRecordBody) {
                    const responseBody = _tryReadXHRBody({ body: xhr.response, url });
                    if ((responseBody === null || responseBody === void 0 ? void 0 : responseBody.length)
                        && _isWithinPayloadLimit(responseBody)) {
                        networkRequest.responseBody = responseBody;
                    }
                }
            });
            // @ts-ignore
            xhr.networkRequest = networkRequest;
            originalOpen.call(xhr, method, url, async, username, password);
        };
    })(XMLHttpRequest.prototype);
}
//# sourceMappingURL=xhr.js.map