"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module RpcInterface
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.WebAppRpcProtocol = void 0;
const core_bentley_1 = require("@itwin/core-bentley");
const CommonLoggerCategory_1 = require("../../CommonLoggerCategory");
const RpcConstants_1 = require("../core/RpcConstants");
const RpcProtocol_1 = require("../core/RpcProtocol");
const OpenAPI_1 = require("./OpenAPI");
const WebAppRpcLogging_1 = require("./WebAppRpcLogging");
const WebAppRpcRequest_1 = require("./WebAppRpcRequest");
/** The HTTP application protocol.
 * @internal
 */
class WebAppRpcProtocol extends RpcProtocol_1.RpcProtocol {
    /** Convenience handler for an RPC operation get request for an HTTP server. */
    async handleOperationGetRequest(req, res) {
        return this.handleOperationPostRequest(req, res);
    }
    /** Convenience handler for an RPC operation post request for an HTTP server. */
    async handleOperationPostRequest(req, res) {
        let request;
        try {
            request = await WebAppRpcRequest_1.WebAppRpcRequest.parseRequest(this, req);
        }
        catch (error) {
            const message = core_bentley_1.BentleyError.getErrorMessage(error);
            core_bentley_1.Logger.logError(CommonLoggerCategory_1.CommonLoggerCategory.RpcInterfaceBackend, `Failed to parse request: ${message}`, core_bentley_1.BentleyError.getErrorMetadata(error));
            res.status(400);
            res.send(JSON.stringify({ message, isError: true }));
            return;
        }
        const fulfillment = await this.fulfill(request);
        await WebAppRpcRequest_1.WebAppRpcRequest.sendResponse(this, request, fulfillment, req, res);
    }
    /** Convenience handler for an OpenAPI description request for an HTTP server. */
    handleOpenApiDescriptionRequest(_req, res) {
        const description = JSON.stringify(this.openAPIDescription);
        res.send(description);
    }
    /** Converts an HTTP content type value to an RPC content type value. */
    static computeContentType(httpType) {
        if (!httpType)
            return RpcConstants_1.RpcContentType.Unknown;
        if (httpType.indexOf(RpcConstants_1.WEB_RPC_CONSTANTS.ANY_TEXT) === 0) {
            return RpcConstants_1.RpcContentType.Text;
        }
        else if (httpType.indexOf(RpcConstants_1.WEB_RPC_CONSTANTS.BINARY) === 0) {
            return RpcConstants_1.RpcContentType.Binary;
        }
        else if (httpType.indexOf(RpcConstants_1.WEB_RPC_CONSTANTS.MULTIPART) === 0) {
            return RpcConstants_1.RpcContentType.Multipart;
        }
        else {
            return RpcConstants_1.RpcContentType.Unknown;
        }
    }
    /** Supplies the status corresponding to a protocol-specific code value. */
    getStatus(code) {
        switch (code) {
            case 404: return RpcConstants_1.RpcRequestStatus.NotFound;
            case 202: return RpcConstants_1.RpcRequestStatus.Pending;
            case 200: return RpcConstants_1.RpcRequestStatus.Resolved;
            case 500: return RpcConstants_1.RpcRequestStatus.Rejected;
            case 204: return RpcConstants_1.RpcRequestStatus.NoContent;
            case 502: return RpcConstants_1.RpcRequestStatus.BadGateway;
            case 503: return RpcConstants_1.RpcRequestStatus.ServiceUnavailable;
            case 504: return RpcConstants_1.RpcRequestStatus.GatewayTimeout;
            case 408: return RpcConstants_1.RpcRequestStatus.RequestTimeout;
            case 429: return RpcConstants_1.RpcRequestStatus.TooManyRequests;
            default: return RpcConstants_1.RpcRequestStatus.Unknown;
        }
    }
    /** Supplies the protocol-specific code corresponding to a status value. */
    getCode(status) {
        switch (status) {
            case RpcConstants_1.RpcRequestStatus.NotFound: return 404;
            case RpcConstants_1.RpcRequestStatus.Pending: return 202;
            case RpcConstants_1.RpcRequestStatus.Resolved: return 200;
            case RpcConstants_1.RpcRequestStatus.Rejected: return 500;
            case RpcConstants_1.RpcRequestStatus.NoContent: return 204;
            case RpcConstants_1.RpcRequestStatus.BadGateway: return 502;
            case RpcConstants_1.RpcRequestStatus.ServiceUnavailable: return 503;
            case RpcConstants_1.RpcRequestStatus.GatewayTimeout: return 504;
            case RpcConstants_1.RpcRequestStatus.RequestTimeout: return 408;
            case RpcConstants_1.RpcRequestStatus.TooManyRequests: return 429;
            default: return 501;
        }
    }
    /** Whether an HTTP status code indicates a request timeout. */
    isTimeout(code) {
        return code === 504;
    }
    /** An OpenAPI-compatible description of this protocol.
     * @internal
     */
    get openAPIDescription() { return new OpenAPI_1.RpcOpenAPIDescription(this); }
    /** Constructs an HTTP protocol. */
    constructor(configuration) {
        super(configuration);
        this.preserveStreams = true;
        /** An optional prefix for RPC operation URI paths. */
        this.pathPrefix = "";
        /** The RPC request class for this protocol. */
        this.requestType = WebAppRpcRequest_1.WebAppRpcRequest;
        this.supportsStatusCategory = true;
        this.events.addListener(async (event, object) => WebAppRpcLogging_1.WebAppRpcLogging.logProtocolEvent(event, object));
    }
}
exports.WebAppRpcProtocol = WebAppRpcProtocol;
//# sourceMappingURL=WebAppRpcProtocol.js.map