"use strict";
/**
 * -------------------------------------------------------------------------------------------
 * Copyright (c) Microsoft Corporation.  All Rights Reserved.  Licensed under the MIT License.
 * See License in the project root for license information.
 * -------------------------------------------------------------------------------------------
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.GraphResponseHandler = exports.DocumentType = void 0;
var tslib_1 = require("tslib");
var ResponseType_1 = require("./ResponseType");
/**
 * @enum
 * Enum for document types
 * @property {string} TEXT_HTML - The text/html content type
 * @property {string} TEXT_XML - The text/xml content type
 * @property {string} APPLICATION_XML - The application/xml content type
 * @property {string} APPLICATION_XHTML - The application/xhml+xml content type
 */
var DocumentType;
(function (DocumentType) {
    DocumentType["TEXT_HTML"] = "text/html";
    DocumentType["TEXT_XML"] = "text/xml";
    DocumentType["APPLICATION_XML"] = "application/xml";
    DocumentType["APPLICATION_XHTML"] = "application/xhtml+xml";
})(DocumentType || (exports.DocumentType = DocumentType = {}));
/**
 * @enum
 * Enum for Content types
 * @property {string} TEXT_PLAIN - The text/plain content type
 * @property {string} APPLICATION_JSON - The application/json content type
 */
var ContentType;
(function (ContentType) {
    ContentType["TEXT_PLAIN"] = "text/plain";
    ContentType["APPLICATION_JSON"] = "application/json";
})(ContentType || (ContentType = {}));
/**
 * @enum
 * Enum for Content type regex
 * @property {string} DOCUMENT - The regex to match document content types
 * @property {string} IMAGE - The regex to match image content types
 */
var ContentTypeRegexStr;
(function (ContentTypeRegexStr) {
    ContentTypeRegexStr["DOCUMENT"] = "^(text\\/(html|xml))|(application\\/(xml|xhtml\\+xml))$";
    ContentTypeRegexStr["IMAGE"] = "^image\\/.+";
})(ContentTypeRegexStr || (ContentTypeRegexStr = {}));
/**
 * @class
 * Class for GraphResponseHandler
 */
var GraphResponseHandler = /** @class */ (function () {
    function GraphResponseHandler() {
    }
    /**
     * @private
     * @static
     * To parse Document response
     * @param {Response} rawResponse - The response object
     * @param {DocumentType} type - The type to which the document needs to be parsed
     * @returns A promise that resolves to a document content
     */
    GraphResponseHandler.parseDocumentResponse = function (rawResponse, type) {
        if (typeof DOMParser !== "undefined") {
            return new Promise(function (resolve, reject) {
                rawResponse.text().then(function (xmlString) {
                    try {
                        var parser = new DOMParser();
                        var xmlDoc = parser.parseFromString(xmlString, type);
                        resolve(xmlDoc);
                    }
                    catch (error) {
                        reject(error);
                    }
                });
            });
        }
        else {
            return Promise.resolve(rawResponse.body);
        }
    };
    /**
     * @private
     * @static
     * @async
     * To convert the native Response to response content
     * @param {Response} rawResponse - The response object
     * @param {ResponseType} [responseType] - The response type value
     * @returns A promise that resolves to the converted response content
     */
    GraphResponseHandler.convertResponse = function (rawResponse, responseType) {
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            var responseValue, contentType, _a, mimeType;
            return tslib_1.__generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        if (rawResponse.status === 204) {
                            // NO CONTENT
                            return [2 /*return*/, Promise.resolve()];
                        }
                        contentType = rawResponse.headers.get("Content-type");
                        _a = responseType;
                        switch (_a) {
                            case ResponseType_1.ResponseType.ARRAYBUFFER: return [3 /*break*/, 1];
                            case ResponseType_1.ResponseType.BLOB: return [3 /*break*/, 3];
                            case ResponseType_1.ResponseType.DOCUMENT: return [3 /*break*/, 5];
                            case ResponseType_1.ResponseType.JSON: return [3 /*break*/, 7];
                            case ResponseType_1.ResponseType.STREAM: return [3 /*break*/, 9];
                            case ResponseType_1.ResponseType.TEXT: return [3 /*break*/, 11];
                        }
                        return [3 /*break*/, 13];
                    case 1: return [4 /*yield*/, rawResponse.arrayBuffer()];
                    case 2:
                        responseValue = _b.sent();
                        return [3 /*break*/, 24];
                    case 3: return [4 /*yield*/, rawResponse.blob()];
                    case 4:
                        responseValue = _b.sent();
                        return [3 /*break*/, 24];
                    case 5: return [4 /*yield*/, GraphResponseHandler.parseDocumentResponse(rawResponse, DocumentType.TEXT_XML)];
                    case 6:
                        responseValue = _b.sent();
                        return [3 /*break*/, 24];
                    case 7: return [4 /*yield*/, rawResponse.json()];
                    case 8:
                        responseValue = _b.sent();
                        return [3 /*break*/, 24];
                    case 9: return [4 /*yield*/, Promise.resolve(rawResponse.body)];
                    case 10:
                        responseValue = _b.sent();
                        return [3 /*break*/, 24];
                    case 11: return [4 /*yield*/, rawResponse.text()];
                    case 12:
                        responseValue = _b.sent();
                        return [3 /*break*/, 24];
                    case 13:
                        if (!(contentType !== null)) return [3 /*break*/, 22];
                        mimeType = contentType.split(";")[0];
                        if (!new RegExp(ContentTypeRegexStr.DOCUMENT).test(mimeType)) return [3 /*break*/, 15];
                        return [4 /*yield*/, GraphResponseHandler.parseDocumentResponse(rawResponse, mimeType)];
                    case 14:
                        responseValue = _b.sent();
                        return [3 /*break*/, 21];
                    case 15:
                        if (!new RegExp(ContentTypeRegexStr.IMAGE).test(mimeType)) return [3 /*break*/, 16];
                        responseValue = rawResponse.blob();
                        return [3 /*break*/, 21];
                    case 16:
                        if (!(mimeType === ContentType.TEXT_PLAIN)) return [3 /*break*/, 18];
                        return [4 /*yield*/, rawResponse.text()];
                    case 17:
                        responseValue = _b.sent();
                        return [3 /*break*/, 21];
                    case 18:
                        if (!(mimeType === ContentType.APPLICATION_JSON)) return [3 /*break*/, 20];
                        return [4 /*yield*/, rawResponse.json()];
                    case 19:
                        responseValue = _b.sent();
                        return [3 /*break*/, 21];
                    case 20:
                        responseValue = Promise.resolve(rawResponse.body);
                        _b.label = 21;
                    case 21: return [3 /*break*/, 23];
                    case 22:
                        /**
                         * RFC specification {@link https://tools.ietf.org/html/rfc7231#section-3.1.1.5} says:
                         *  A sender that generates a message containing a payload body SHOULD
                         *  generate a Content-Type header field in that message unless the
                         *  intended media type of the enclosed representation is unknown to the
                         *  sender.  If a Content-Type header field is not present, the recipient
                         *  MAY either assume a media type of "application/octet-stream"
                         *  ([RFC2046], Section 4.5.1) or examine the data to determine its type.
                         *
                         *  So assuming it as a stream type so returning the body.
                         */
                        responseValue = Promise.resolve(rawResponse.body);
                        _b.label = 23;
                    case 23: return [3 /*break*/, 24];
                    case 24: return [2 /*return*/, responseValue];
                }
            });
        });
    };
    /**
     * @public
     * @static
     * @async
     * To get the parsed response
     * @param {Response} rawResponse - The response object
     * @param {ResponseType} [responseType] - The response type value
     * @param {GraphRequestCallback} [callback] - The graph request callback function
     * @returns The parsed response
     */
    GraphResponseHandler.getResponse = function (rawResponse, responseType, callback) {
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            var response;
            return tslib_1.__generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        if (!(responseType === ResponseType_1.ResponseType.RAW)) return [3 /*break*/, 1];
                        return [2 /*return*/, Promise.resolve(rawResponse)];
                    case 1: return [4 /*yield*/, GraphResponseHandler.convertResponse(rawResponse, responseType)];
                    case 2:
                        response = _a.sent();
                        if (rawResponse.ok) {
                            // Status Code 2XX
                            if (typeof callback === "function") {
                                callback(null, response);
                            }
                            else {
                                return [2 /*return*/, response];
                            }
                        }
                        else {
                            // NOT OK Response
                            throw response;
                        }
                        _a.label = 3;
                    case 3: return [2 /*return*/];
                }
            });
        });
    };
    return GraphResponseHandler;
}());
exports.GraphResponseHandler = GraphResponseHandler;
//# sourceMappingURL=GraphResponseHandler.js.map