"use strict";
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 () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.workspaceContext = exports.schemaRequestHandler = void 0;
const path_1 = require("path");
const request_light_1 = require("request-light");
const URL = __importStar(require("url"));
const vscode_languageserver_1 = require("vscode-languageserver");
const vscode_uri_1 = require("vscode-uri");
const requestTypes_1 = require("../../requestTypes");
const paths_1 = require("../utils/paths");
// eslint-disable-next-line @typescript-eslint/no-namespace
var FSReadUri;
(function (FSReadUri) {
    FSReadUri.type = new vscode_languageserver_1.RequestType('fs/readUri');
})(FSReadUri || (FSReadUri = {}));
/**
 * Handles schema content requests given the schema URI
 * @param uri can be a local file, vscode request, http(s) request or a custom request
 */
const schemaRequestHandler = async (connection, uri, workspaceFolders, workspaceRoot, useVSCodeContentRequest, fs, isWeb) => {
    if (!uri) {
        return Promise.reject('No schema specified');
    }
    // If the requested schema URI is a relative file path
    // Convert it into a proper absolute path URI
    if ((0, paths_1.isRelativePath)(uri)) {
        // HACK: the fs/readUri extension is only available with vscode-yaml,
        // and this fix is specific to vscode-yaml on web, so don't use it in other cases
        if (workspaceFolders.length === 1 && isWeb) {
            const wsUri = vscode_uri_1.URI.parse(workspaceFolders[0].uri);
            const wsDirname = wsUri.path;
            const modifiedUri = wsUri.with({ path: (0, path_1.join)(wsDirname, uri) });
            try {
                return connection.sendRequest(FSReadUri.type, modifiedUri.toString());
            }
            catch (e) {
                connection.window.showErrorMessage(`failed to get content of '${modifiedUri}': ${e}`);
            }
        }
        else {
            uri = (0, paths_1.relativeToAbsolutePath)(workspaceFolders, workspaceRoot, uri);
        }
    }
    let scheme = vscode_uri_1.URI.parse(uri).scheme.toLowerCase();
    // test if uri is windows path, ie starts with 'c:\'
    if (/^[a-z]:[\\/]/i.test(uri)) {
        const winUri = vscode_uri_1.URI.file(uri);
        scheme = winUri.scheme.toLowerCase();
        uri = winUri.toString();
    }
    // If the requested schema is a local file, read and return the file contents
    if (scheme === 'file') {
        const fsPath = vscode_uri_1.URI.parse(uri).fsPath;
        return fs.readFile(fsPath, 'UTF-8').catch(() => {
            // If there was an error reading the file, return empty error message
            // Otherwise return the file contents as a string
            return '';
        });
    }
    // HTTP(S) requests are sent and the response result is either the schema content or an error
    if (scheme === 'http' || scheme === 'https') {
        // If we are running inside of VSCode we need to make a content request. This content request
        // will make it so that schemas behind VPN's will resolve correctly
        if (useVSCodeContentRequest) {
            try {
                return await connection.sendRequest(requestTypes_1.VSCodeContentRequest.type, uri);
            }
            catch (error) {
                throw error.message;
            }
        }
        // Send the HTTP(S) schema content request and return the result
        const version = (typeof process !== 'undefined' && process.env.YAML_LANGUAGE_SERVER_VERSION) || 'unknown';
        const nodeVersion = typeof process !== 'undefined' && process.versions?.node ? ` node/${process.versions.node}` : '';
        const platform = typeof process !== 'undefined' && process.platform ? ` (${process.platform})` : '';
        const headers = {
            'Accept-Encoding': 'gzip, deflate',
            'User-Agent': `yaml-language-server/${version} (RedHat)${nodeVersion}${platform}`,
        };
        try {
            const response = await (0, request_light_1.xhr)({ url: uri, followRedirects: 5, headers });
            return response.responseText;
        }
        catch (error) {
            throw error.responseText || (0, request_light_1.getErrorStatusDescription)(error.status) || error.toString();
        }
    }
    // Neither local file nor vscode, nor HTTP(S) schema request, so send it off as a custom request
    return connection.sendRequest(requestTypes_1.CustomSchemaContentRequest.type, uri);
};
exports.schemaRequestHandler = schemaRequestHandler;
exports.workspaceContext = {
    resolveRelativePath: (relativePath, resource) => {
        return URL.resolve(resource, relativePath);
    },
};
//# sourceMappingURL=schemaRequestHandler.js.map