"use strict";
/*
 *  Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *  SPDX-License-Identifier: Apache-2.0
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.handler = void 0;
const axios_1 = __importStar(require("axios"));
const lodash_1 = __importDefault(require("lodash"));
const HttpError_1 = __importDefault(require("../integration-tests/support/utils/HttpError"));
/* eslint-disable-next-line */
async function handler(event) {
    const baseUrl = process.env.API_GW_URL.replace('/dev/', '/dev');
    let HTTP_METHOD = '';
    let reqHeaders = {};
    const response = {
        statusCode: 200,
        statusDescription: '',
        body: undefined,
        isBase64Encoded: false,
        multiValueHeaders: { 'Content-Type': ['application/json'] },
        headers: { 'Content-Type': 'application/json' }
    };
    let body = {};
    let params = {};
    if (event.multiValueHeaders) {
        // In order to support array of cookies for set-cookies, multiValueHeaders is enabled on the ALB target
        // This makes all request headers come in under multiValueHeaders as arrays
        event.headers = {};
        Object.keys(event.multiValueHeaders).forEach((key) => {
            // eslint-disable-next-line security/detect-object-injection
            event.headers[key] = event.multiValueHeaders[key][0];
        });
    }
    // Short-circuit if this is a ALB health-check
    if (event.headers['user-agent'] && event.headers['user-agent'] === 'ELB-HealthChecker/2.0') {
        response.statusDescription = 'OK';
        return setupResponse(response, {}, 200, 'Health check passed', event.headers);
    }
    let apiPath = event.path ? event.path.replace('api/', '') : '';
    if (apiPath[apiPath.length - 1] === '/') {
        // SWB APIs do not have trailing slash, but this gets added when UI passes down the path
        apiPath = apiPath.substring(0, apiPath.length - 1);
    }
    const targetPath = encodeURI(`${baseUrl}${apiPath}`);
    if (event.httpMethod)
        HTTP_METHOD = event.httpMethod;
    if (event.headers) {
        reqHeaders['Content-Type'] = event.headers['content-type'] || 'application/json';
        reqHeaders.Cookie = event.headers.cookie;
        reqHeaders['csrf-token'] = event.headers['csrf-token'];
        reqHeaders['x-forwarded-for'] = event.headers['x-forwarded-for'];
        reqHeaders.connection = event.headers.connection;
        reqHeaders['Access-Control-Allow-Credentials'] = 'true';
        reqHeaders.accept = 'application/json, text/plain, */*';
        reqHeaders.connection = event.headers.connection || 'keep-alive';
        if (!reqHeaders.origin)
            reqHeaders.origin = `https://${event.headers.host}`;
        if (reqHeaders.host) {
            // Have to remove host if it is from the UI to avoid incorrect host being set when sending to Cognito
            // (Should be API GW host, not UI)
            delete reqHeaders.host;
        }
        reqHeaders = lodash_1.default.omitBy(reqHeaders, lodash_1.default.isNil);
    }
    if (event.body && event.body.length !== 0) {
        try {
            body = JSON.parse(event.body);
        }
        catch (err) {
            body = event.body;
        }
    }
    if (event.queryStringParameters) {
        params = event.queryStringParameters;
    }
    else if (event.multiValueQueryStringParameters) {
        // Due to multiValueHeaders, queryStringParameters become multiValueQueryStringParameters
        // with each value wrapped in an array
        params = {};
        Object.keys(event.multiValueQueryStringParameters).forEach((key) => {
            // eslint-disable-next-line security/detect-object-injection
            params[decodeURIComponent(key)] = decodeURIComponent(event.multiValueQueryStringParameters[key][0]);
        });
    }
    function setupResponse(response, data, status, statusText, headers) {
        if (headers['set-cookie']) {
            if (Array.isArray(headers['set-cookie'])) {
                response.multiValueHeaders['set-cookie'] = headers['set-cookie'];
            }
            else {
                response.multiValueHeaders['set-cookie'] = [headers['set-cookie']];
            }
            response.headers['set-cookie'] = headers['set-cookie'];
        }
        response.statusCode = status;
        response.statusDescription = statusText;
        if (data) {
            response.body = JSON.stringify(data);
        }
    }
    try {
        if (HTTP_METHOD === 'GET') {
            const { data, status, statusText, headers } = await axios_1.default.get(targetPath, {
                headers: reqHeaders,
                params,
                withCredentials: true
            });
            setupResponse(response, data, status, statusText, headers);
        }
        if (HTTP_METHOD === 'PATCH') {
            const { data, status, statusText, headers } = await axios_1.default.patch(targetPath, body, {
                headers: reqHeaders,
                params,
                withCredentials: true
            });
            setupResponse(response, data, status, statusText, headers);
        }
        if (HTTP_METHOD === 'POST') {
            const { data, status, statusText, headers } = await axios_1.default.post(targetPath, body, {
                headers: reqHeaders,
                params,
                withCredentials: true
            });
            setupResponse(response, data, status, statusText, headers);
        }
        if (HTTP_METHOD === 'PUT') {
            const { data, status, statusText, headers } = await axios_1.default.put(targetPath, body, {
                headers: reqHeaders,
                params,
                withCredentials: true
            });
            setupResponse(response, data, status, statusText, headers);
        }
        if (HTTP_METHOD === 'DELETE') {
            const { data, status, statusText, headers } = await axios_1.default.delete(targetPath, {
                headers: reqHeaders,
                params,
                withCredentials: true
            });
            setupResponse(response, data, status, statusText, headers);
        }
    }
    catch (err) {
        if (!(err instanceof axios_1.AxiosError) || !err.response) {
            console.error(`Unsupported error encountered: ${JSON.stringify(err)}`);
            throw err;
        }
        const error = new HttpError_1.default(err.response.status, JSON.stringify({
            error: err.response.data.error,
            message: err.response.data.message
        }), err.response.statusText);
        error.isBase64Encoded = false;
        error.headers = { 'Content-Type': 'application/json' };
        console.error('Application error encountered', error);
        // The error object has to be returned like this for integration tests' backwards compatibility
        return error;
    }
    return response;
}
exports.handler = handler;
//# sourceMappingURL=proxyHandlerLambda.js.map