import { Strings } from '@devvit/protos/types/devvit/runtime/runtime_common.js';
import { Header } from '@devvit/shared-types/Header.js';
// TODO: remove use of any below
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function mockPath(pool, expectedObj) {
    const requestObj = {}; // Refers to the mocked request object
    const status = expectedObj.status || 200;
    // responseObj is the expected response from the mocked request
    const responseObj = expectedObj.error || expectedObj.expectedBody || {};
    pool
        .intercept({
        path: pathMatcher(expectedObj.path),
        method: expectedObj.method,
    })
        // TODO: remove use of any below
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        .reply(status, (opts) => {
        requestObj.path = opts.path;
        requestObj.body = opts.body;
        requestObj.headers = opts.headers;
        requestObj.hit = true;
        return responseObj;
    });
    return requestObj;
}
// TODO: remove use of any below
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function getNestedProp(root, propName) {
    const parts = propName.split('.');
    // TODO: remove use of any below
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    let curr = root;
    for (const part of parts) {
        if (!curr)
            throw 'Unknown property';
        curr = curr[part];
    }
    return curr;
}
export function getMetadata(withAuth = true) {
    const md = {
        [Header.R2Host]: Strings.fromPartial({ values: ['oauth.reddit.com'] }),
        [Header.App]: Strings.fromPartial({ values: ['my-app'] }),
    };
    if (withAuth) {
        md[Header.R2Auth] = Strings.fromPartial({ values: ['123456789'] });
    }
    return md;
}
/**
 * @param headers - The headers object from the request
 * @param key - The header key to get. This function tries to be case-insensitive, so it will
 *             try to find the header key first using the original case, and if that fails,
 *             it will try again using the lower case version of the key.
 */
export function getHeader(headers, key) {
    let res;
    // Short circuit if headers is actually an object
    if (!(headers instanceof Array)) {
        res = headers[key];
    }
    else {
        let val = '';
        for (let i = 0; i < headers.length; i++) {
            if (headers[i] === key && i + 1 < headers.length) {
                val = headers[i + 1];
                break;
            }
        }
        res = val;
    }
    if (res != null) {
        return res;
    }
    if (key.toLowerCase() === key) {
        return res;
    }
    return getHeader(headers, key.toLowerCase());
}
export function decodeAndParse(arr) {
    const str = new TextDecoder().decode(arr);
    return JSON.parse(str);
}
export function decodeAndParseFormData(arr) {
    const str = new TextDecoder().decode(arr);
    const params = new URLSearchParams(str);
    const retObj = {};
    params.forEach((val, key) => (retObj[key] = val));
    return retObj;
}
/**
 * Undici's Interceptable.intercept() method arguments define `path` as string | RegEx | Function
 * to give different levels of control over how paths are intercepted and mocked. Since raw_json=1
 * is dynamically added to every API request the exact string matcher no longer works since
 * /foo != /foo?raw_json=1.  Each API has a concrete path but variable query parameters, so we
 * can safely match on just the path by stripping the query parameters off before comparing.
 */
export function pathMatcher(expectedPath) {
    const expectedPathNoQuery = expectedPath.split('?')[0];
    return (path) => path.split('?')[0] === expectedPathNoQuery;
}
