"use strict";
/**
 * Copyright (c) "Neo4j"
 * Neo4j Sweden AB [https://neo4j.com]
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = create;
var neo4j_driver_core_1 = require("neo4j-driver-core");
var bolt_protocol_v1_1 = __importDefault(require("./bolt-protocol-v1"));
var bolt_protocol_v2_1 = __importDefault(require("./bolt-protocol-v2"));
var bolt_protocol_v3_1 = __importDefault(require("./bolt-protocol-v3"));
var bolt_protocol_v4x0_1 = __importDefault(require("./bolt-protocol-v4x0"));
var bolt_protocol_v4x1_1 = __importDefault(require("./bolt-protocol-v4x1"));
var bolt_protocol_v4x2_1 = __importDefault(require("./bolt-protocol-v4x2"));
var bolt_protocol_v4x3_1 = __importDefault(require("./bolt-protocol-v4x3"));
var bolt_protocol_v4x4_1 = __importDefault(require("./bolt-protocol-v4x4"));
var bolt_protocol_v5x0_1 = __importDefault(require("./bolt-protocol-v5x0"));
var bolt_protocol_v5x1_1 = __importDefault(require("./bolt-protocol-v5x1"));
var bolt_protocol_v5x2_1 = __importDefault(require("./bolt-protocol-v5x2"));
var bolt_protocol_v5x3_1 = __importDefault(require("./bolt-protocol-v5x3"));
var bolt_protocol_v5x4_1 = __importDefault(require("./bolt-protocol-v5x4"));
var bolt_protocol_v5x5_1 = __importDefault(require("./bolt-protocol-v5x5"));
var bolt_protocol_v5x6_1 = __importDefault(require("./bolt-protocol-v5x6"));
var bolt_protocol_v5x7_1 = __importDefault(require("./bolt-protocol-v5x7"));
var bolt_protocol_v5x8_1 = __importDefault(require("./bolt-protocol-v5x8"));
// eslint-disable-next-line no-unused-vars
var channel_1 = require("../channel");
var response_handler_1 = __importDefault(require("./response-handler"));
/**
 * Creates a protocol with a given version
 *
 * @param {object} config
 * @param {number} config.version The version of the protocol
 * @param {channel} config.channel The channel
 * @param {Chunker} config.chunker The chunker
 * @param {Dechunker} config.dechunker The dechunker
 * @param {Logger} config.log The logger
 * @param {ResponseHandler~Observer} config.observer Observer
 * @param {boolean} config.disableLosslessIntegers Disable the lossless integers
 * @param {boolean} packstreamConfig.useBigInt if this connection should convert all received integers to native BigInt numbers.
 * @param {boolean} config.serversideRouting It's using server side routing
 */
function create(_a) {
    var _b = _a === void 0 ? {} : _a, version = _b.version, chunker = _b.chunker, dechunker = _b.dechunker, channel = _b.channel, disableLosslessIntegers = _b.disableLosslessIntegers, useBigInt = _b.useBigInt, serversideRouting = _b.serversideRouting, server = _b.server, // server info
    log = _b.log, observer = _b.observer;
    var createResponseHandler = function (protocol) {
        var responseHandler = new response_handler_1.default({
            transformMetadata: protocol.transformMetadata.bind(protocol),
            enrichErrorMetadata: protocol.enrichErrorMetadata.bind(protocol),
            log: log,
            observer: observer
        });
        // reset the error handler to just handle errors and forget about the handshake promise
        channel.onerror = observer.onError.bind(observer);
        // Ok, protocol running. Simply forward all messages to the dechunker
        channel.onmessage = function (buf) { return dechunker.write(buf); };
        // setup dechunker to dechunk messages and forward them to the message handler
        dechunker.onmessage = function (buf) {
            try {
                responseHandler.handleResponse(protocol.unpack(buf));
            }
            catch (e) {
                return observer.onError(e);
            }
        };
        return responseHandler;
    };
    return createProtocol(version, server, chunker, { disableLosslessIntegers: disableLosslessIntegers, useBigInt: useBigInt }, serversideRouting, createResponseHandler, observer.onProtocolError.bind(observer), log);
}
function createProtocol(version, server, chunker, packingConfig, serversideRouting, createResponseHandler, onProtocolError, log) {
    switch (version) {
        case 1:
            return new bolt_protocol_v1_1.default(server, chunker, packingConfig, createResponseHandler, log, onProtocolError);
        case 2:
            return new bolt_protocol_v2_1.default(server, chunker, packingConfig, createResponseHandler, log, onProtocolError);
        case 3:
            return new bolt_protocol_v3_1.default(server, chunker, packingConfig, createResponseHandler, log, onProtocolError);
        case 4.0:
            return new bolt_protocol_v4x0_1.default(server, chunker, packingConfig, createResponseHandler, log, onProtocolError);
        case 4.1:
            return new bolt_protocol_v4x1_1.default(server, chunker, packingConfig, createResponseHandler, log, onProtocolError, serversideRouting);
        case 4.2:
            return new bolt_protocol_v4x2_1.default(server, chunker, packingConfig, createResponseHandler, log, onProtocolError, serversideRouting);
        case 4.3:
            return new bolt_protocol_v4x3_1.default(server, chunker, packingConfig, createResponseHandler, log, onProtocolError, serversideRouting);
        case 4.4:
            return new bolt_protocol_v4x4_1.default(server, chunker, packingConfig, createResponseHandler, log, onProtocolError, serversideRouting);
        case 5.0:
            return new bolt_protocol_v5x0_1.default(server, chunker, packingConfig, createResponseHandler, log, onProtocolError, serversideRouting);
        case 5.1:
            return new bolt_protocol_v5x1_1.default(server, chunker, packingConfig, createResponseHandler, log, onProtocolError, serversideRouting);
        case 5.2:
            return new bolt_protocol_v5x2_1.default(server, chunker, packingConfig, createResponseHandler, log, onProtocolError, serversideRouting);
        case 5.3:
            return new bolt_protocol_v5x3_1.default(server, chunker, packingConfig, createResponseHandler, log, onProtocolError, serversideRouting);
        case 5.4:
            return new bolt_protocol_v5x4_1.default(server, chunker, packingConfig, createResponseHandler, log, onProtocolError, serversideRouting);
        case 5.5:
            return new bolt_protocol_v5x5_1.default(server, chunker, packingConfig, createResponseHandler, log, onProtocolError, serversideRouting);
        case 5.6:
            return new bolt_protocol_v5x6_1.default(server, chunker, packingConfig, createResponseHandler, log, onProtocolError, serversideRouting);
        case 5.7:
            return new bolt_protocol_v5x7_1.default(server, chunker, packingConfig, createResponseHandler, log, onProtocolError, serversideRouting);
        case 5.8:
            return new bolt_protocol_v5x8_1.default(server, chunker, packingConfig, createResponseHandler, log, onProtocolError, serversideRouting);
        default:
            throw (0, neo4j_driver_core_1.newError)('Unknown Bolt protocol version: ' + version);
    }
}
