/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

'use strict';

const ComplexObjectType = require('./ObjectType').ComplexObjectType;
const ObjectArrayType = require('./ObjectType').ObjectArrayType;
const BinaryUtils = require('./internal/BinaryUtils');
const BinaryCommunicator = require('./internal/BinaryCommunicator');
const ArgumentChecker = require('./internal/ArgumentChecker');
const Errors = require('./Errors');

/**
 * Class representing Cache Key part of Ignite {@link CacheConfiguration}.
 *
 * All configuration settings are optional and have defaults which are defined on a server side.
 *
 * See Apache Ignite documentation for details of every configuration setting. 
 */
class CacheKeyConfiguration {

    /**
     * Public constructor.
     *
     * @param {string} [typeName=null]
     * @param {string} [affinityKeyFieldName=null]
     *
     * @return {CacheKeyConfiguration} - new CacheKeyConfiguration instance.
     */
    constructor(typeName = null, affinityKeyFieldName = null) {
        this._typeName = typeName;
        this._affinityKeyFieldName = affinityKeyFieldName;
    }

    /**
     *
     *
     * @param {string} typeName
     *
     * @return {CacheKeyConfiguration} - the same instance of the CacheKeyConfiguration.
     */
    setTypeName(typeName) {
        this._typeName = typeName;
        return this;
    }

    /**
     *
     *
     * @return {string}
     */
    getTypeName() {
        return this._typeName;
    }

    /**
     *
     *
     * @param {string} affinityKeyFieldName
     *
     * @return {CacheKeyConfiguration} - the same instance of the CacheKeyConfiguration.
     */
    setAffinityKeyFieldName(affinityKeyFieldName) {
        this._affinityKeyFieldName = affinityKeyFieldName;
        return this;
    }

    /**
     *
     *
     * @return {string}
     */
    getAffinityKeyFieldName() {
        return this._affinityKeyFieldName;
    }

    /** Private methods */

    /**
     * @ignore
     */
    async _write(communicator, buffer) {
        BinaryCommunicator.writeString(buffer, this._typeName);
        BinaryCommunicator.writeString(buffer, this._affinityKeyFieldName);
    }

    /**
     * @ignore
     */
    async _read(communicator, buffer) {
        this._typeName = BinaryCommunicator.readString(buffer);
        this._affinityKeyFieldName = BinaryCommunicator.readString(buffer);
    }
}

/**
 * Class representing one Query Entity element of Ignite {@link CacheConfiguration}.
 *
 * All configuration settings are optional and have defaults which are defined on a server side.
 *
 * See Apache Ignite documentation for details of every configuration setting. 
 */
class QueryEntity {

    /**
     * Public constructor.
     *
     * @return {QueryEntity} - new QueryEntity instance.
     */
    constructor() {
        this._keyTypeName = null;
        this._valueTypeName = null;
        this._tableName = null;
        this._keyFieldName = null;
        this._valueFieldName = null;
        this._fields = null;
        this._aliases = null;
        this._indexes = null;
    }

    /**
     *
     *
     * @param {string} keyTypeName
     *
     * @return {QueryEntity} - the same instance of the QueryEntity.
     */
    setKeyTypeName(keyTypeName) {
        this._keyTypeName = keyTypeName;
        return this;
    }

    /**
     *
     *
     * @return {string}
     */
    getKeyTypeName() {
        return this._keyTypeName;
    }

    /**
     *
     *
     * @param {string} valueTypeName
     *
     * @return {QueryEntity} - the same instance of the QueryEntity.
     */
    setValueTypeName(valueTypeName) {
        this._valueTypeName = valueTypeName;
        return this;
    }

    /**
     *
     *
     * @return {string}
     */
    getValueTypeName() {
        return this._valueTypeName;
    }

    /**
     *
     *
     * @param {string} tableName
     *
     * @return {QueryEntity} - the same instance of the QueryEntity.
     */
    setTableName(tableName) {
        this._tableName = tableName;
        return this;
    }

    /**
     *
     *
     * @return {string}
     */
    getTableName() {
        return this._tableName;
    }

    /**
     *
     *
     * @param {string} keyFieldName
     *
     * @return {QueryEntity} - the same instance of the QueryEntity.
     */
    setKeyFieldName(keyFieldName) {
        this._keyFieldName = keyFieldName;
        return this;
    }

    /**
     *
     *
     * @return {string}
     */
    getKeyFieldName() {
        return this._keyFieldName;
    }

    /**
     *
     *
     * @param {string} valueFieldName
     *
     * @return {QueryEntity} - the same instance of the QueryEntity.
     */
    setValueFieldName(valueFieldName) {
        this._valueFieldName = valueFieldName;
        return this;
    }

    /**
     *
     *
     * @return {string}
     */
    getValueFieldName() {
        return this._valueFieldName;
    }

    /**
     * 
     *
     * @param {Array<QueryField>} fields
     *
     * @return {QueryEntity} - the same instance of the QueryEntity.
     */
    setFields(fields) {
        this._fields = fields;
        return this;
    }

    /**
     * 
     *
     * @return {Array<QueryField>}
     */
    getFields() {
        return this._fields;
    }

    /**
     * 
     *
     * @param {Map<string, string>} aliases
     *
     * @return {QueryEntity} - the same instance of the QueryEntity.
     */
    setAliases(aliases) {
        this._aliases = aliases;
        return this;
    }

    /**
     * 
     *
     * @return {Map<string, string>}
     */
    getAliases() {
        return this._aliases;
    }

    /**
     * 
     *
     * @param {Array<QueryIndex>} indexes
     *
     * @return {QueryEntity} - the same instance of the QueryEntity.
     */
    setIndexes(indexes) {
        this._indexes = indexes;
        return this;
    }

    /**
     * 
     *
     * @return {Array<QueryIndex>}
     */
    getIndexes() {
        return this._indexes;
    }

    /** Private methods */

    /**
     * @ignore
     */
    async _write(communicator, buffer) {
        BinaryCommunicator.writeString(buffer, this._keyTypeName);
        BinaryCommunicator.writeString(buffer, this._valueTypeName);
        BinaryCommunicator.writeString(buffer, this._tableName);
        BinaryCommunicator.writeString(buffer, this._keyFieldName);
        BinaryCommunicator.writeString(buffer, this._valueFieldName);
        await this._writeSubEntities(communicator, buffer, this._fields);
        await this._writeAliases(communicator, buffer);
        await this._writeSubEntities(communicator, buffer, this._indexes);
    }

    /**
     * @ignore
     */
    async _writeAliases(communicator, buffer) {
        const length = this._aliases ? this._aliases.size : 0;
        buffer.writeInteger(length);
        if (length > 0) {
            for (let [key, value] of this._aliases.entries()) {
                BinaryCommunicator.writeString(buffer, key);
                BinaryCommunicator.writeString(buffer, value);
            }
        }
    }

    /**
     * @ignore
     */
    async _writeSubEntities(communicator, buffer, entities) {
        const length = entities ? entities.length : 0;
        buffer.writeInteger(length);
        if (length > 0) {
            for (let entity of entities) {
                await entity._write(communicator, buffer);
            }
        }
    }

    /**
     * @ignore
     */
    async _read(communicator, buffer) {
        this._keyTypeName = await communicator.readObject(buffer);
        this._valueTypeName = await communicator.readObject(buffer);
        this._tableName = await communicator.readObject(buffer);
        this._keyFieldName = await communicator.readObject(buffer);
        this._valueFieldName = await communicator.readObject(buffer);
        this._fields = await this._readSubEntities(communicator, buffer, QueryField);
        await this._readAliases(communicator, buffer);
        this._indexes = await this._readSubEntities(communicator, buffer, QueryIndex);
    }

    /**
     * @ignore
     */
    async _readSubEntities(communicator, buffer, objectConstructor) {
        const length = buffer.readInteger(buffer);
        const result = new Array(length);
        if (length > 0) {
            let res;
            for (let i = 0; i < length; i++) {
                res = new objectConstructor();
                await res._read(communicator, buffer);
                result[i] = res;
            }
        }
        return result;
    }

    /**
     * @ignore
     */
    async _readAliases(communicator, buffer) {
        const length = buffer.readInteger(buffer);
        this._aliases = new Map();
        if (length > 0) {
            let res;
            for (let i = 0; i < length; i++) {
                this._aliases.set(await communicator.readObject(buffer), await communicator.readObject(buffer));
            }
        }
    }
}

/**
 * Class representing one Query Field element of {@link QueryEntity} of Ignite {@link CacheConfiguration}.
 *
 * All configuration settings are optional and have defaults which are defined on a server side.
 *
 * See Apache Ignite documentation for details of every configuration setting. 
 */
class QueryField {

    /**
     * Public constructor.
     *
     * @param {string} [name=null]
     * @param {string} [typeName=null]
     *
     * @return {QueryField} - new QueryField instance.
     */
    constructor(name = null, typeName = null) {
        this._name = name;
        this._typeName = typeName;
        this._isKeyField = false;
        this._isNotNull = false;
        this._defaultValue = undefined;
        this._precision = -1;
        this._scale = -1;
        this._valueType = null;
        this._communicator = null;
        this._buffer = null;
        this._index = null;
    }

    /**
     *
     *
     * @param {string} name
     *
     * @return {QueryField} - the same instance of the QueryField.
     */
    setName(name) {
        this._name = name;
        return this;
    }

    /**
     *
     *
     * @return {string}
     */
    getName() {
        return this._name;
    }

    /**
     *
     *
     * @param {string} typeName
     *
     * @return {QueryField} - the same instance of the QueryField.
     */
    setTypeName(typeName) {
        this._typeName = typeName;
        return this;
    }

    /**
     *
     *
     * @return {string}
     */
    getTypeName() {
        return this._typeName;
    }

    /**
     *
     *
     * @param {boolean} isKeyField
     *
     * @return {QueryField} - the same instance of the QueryField.
     */
    setIsKeyField(isKeyField) {
        this._isKeyField = isKeyField;
        return this;
    }

    /**
     *
     *
     * @return {boolean}
     */
    getIsKeyField() {
        return this._isKeyField;
    }

    /**
     *
     *
     * @param {boolean} isNotNull
     *
     * @return {QueryField} - the same instance of the QueryField.
     */
    setIsNotNull(isNotNull) {
        this._isNotNull = isNotNull;
        return this;
    }

    /**
     *
     *
     * @return {boolean}
     */
    getIsNotNull() {
        return this._isNotNull;
    }

    /**
     *
     *
     * @param {*} defaultValue
     * @param {ObjectType.PRIMITIVE_TYPE | CompositeType} [valueType=null] - type of the default value:
     *   - either a type code of primitive (simple) type
     *   - or an instance of class representing non-primitive (composite) type
     *   - or null (or not specified) that means the type is not specified
     *
     * @return {QueryField} - the same instance of the QueryField.
     */
    setDefaultValue(defaultValue, valueType = null) {
        this._defaultValue = defaultValue;
        this._valueType = valueType;
        return this;
    }

    /**
     *
     *
     * @param {ObjectType.PRIMITIVE_TYPE | CompositeType} [valueType=null] - type of the default value:
     *   - either a type code of primitive (simple) type
     *   - or an instance of class representing non-primitive (composite) type
     *   - or null (or not specified) that means the type is not specified
     *
     * @async
     *
     * @return {*}
     */
    async getDefaultValue(valueType = null) {
        if (this._defaultValue === undefined) {
            if (this._buffer) {
                const position = this._buffer.position;
                this._buffer.position = this._index;
                const result = await this._communicator.readObject(this._buffer, valueType);
                this._buffer.position = position;
                return result;
            }
            else {
                return null;
            }
        }
        else {
            return this._defaultValue;
        }
    }

    /**
     *
     *
     * @param {number} precision
     *
     * @return {QueryField} - the same instance of the QueryField.
     */
    setPrecision(precision) {
        ArgumentChecker.isInteger(precision, 'precision');
        this._precision = precision;
        return this;
    }

    /**
     *
     *
     * @return {number}
     */
    getPrecision() {
        return this._precision;
    }

    /**
     *
     *
     * @param {number} scale
     *
     * @return {QueryField} - the same instance of the QueryField.
     */
    setScale(scale) {
        ArgumentChecker.isInteger(scale, 'scale');
        this._scale = scale;
        return this;
    }

    /**
     *
     *
     * @return {number}
     */
    getScale() {
        return this._scale;
    }

    /** Private methods */

    /**
     * @ignore
     */
    async _write(communicator, buffer) {
        BinaryCommunicator.writeString(buffer, this._name);
        BinaryCommunicator.writeString(buffer, this._typeName);
        buffer.writeBoolean(this._isKeyField);
        buffer.writeBoolean(this._isNotNull);
        await communicator.writeObject(buffer, this._defaultValue ? this._defaultValue : null, this._valueType);
        buffer.writeInteger(this._precision);
        buffer.writeInteger(this._scale);
    }

    /**
     * @ignore
     */
    async _read(communicator, buffer) {
        this._name = await communicator.readObject(buffer);
        this._typeName = await communicator.readObject(buffer);
        this._isKeyField = buffer.readBoolean();
        this._isNotNull = buffer.readBoolean();
        this._defaultValue = undefined;
        this._communicator = communicator;
        this._buffer = buffer;
        this._index = buffer.position;
        await communicator.readObject(buffer);
        this._precision = buffer.readInteger();
        this._scale = buffer.readInteger();
    }
}

/**
 * 
 * @typedef QueryIndex.INDEX_TYPE
 * @enum
 * @readonly
 * @property SORTED 0
 * @property FULLTEXT 1
 * @property GEOSPATIAL 2
 */
 const INDEX_TYPE = Object.freeze({
    SORTED : 0,
    FULLTEXT : 1,
    GEOSPATIAL : 2
});

/**
 * Class representing one Query Index element of {@link QueryEntity} of Ignite {@link CacheConfiguration}.
 *
 * All configuration settings are optional and have defaults which are defined on a server side.
 *
 * See Apache Ignite documentation for details of every configuration setting. 
 */
class QueryIndex {
    
    /**
     * Public constructor.
     *
     * @param {string} [name=null]
     * @param {string} [typeName=QueryIndex.INDEX_TYPE.SORTED]
     *
     * @return {QueryIndex} - new QueryIndex instance.
     */
    constructor(name = null, type = QueryIndex.INDEX_TYPE.SORTED) {
        this._name = name;
        this.setType(type);
        this._inlineSize = -1;
        this._fields = null;
    }

    static get INDEX_TYPE() {
        return INDEX_TYPE;
    }

    /**
     *
     *
     * @param {string} name
     *
     * @return {QueryIndex} - the same instance of the QueryIndex.
     */
    setName(name) {
        this._name = name;
        return this;
    }

    /**
     *
     *
     * @return {string}
     */
    getName() {
        return this._name;
    }

    /**
     *
     *
     * @param {QueryIndex.INDEX_TYPE} type
     *
     * @return {QueryIndex} - the same instance of the QueryIndex.
     *
     * @throws {IgniteClientError} if error.
     */
    setType(type) {
        ArgumentChecker.hasValueFrom(type, 'type', false, QueryIndex.INDEX_TYPE);
        this._type = type;
        return this;
    }

    /**
     *
     *
     * @return {QueryIndex.INDEX_TYPE}
     */
    getType() {
        return this._type;
    }

    /**
     *
     *
     * @param {number} inlineSize
     *
     * @return {QueryIndex} - the same instance of the QueryIndex.
     */
    setInlineSize(inlineSize) {
        this._inlineSize = inlineSize;
        return this;
    }

    /**
     *
     *
     * @return {number}
     */
    getInlineSize() {
        return this._inlineSize;
    }

    /**
     * 
     *
     * @param {Map<string, boolean>} fields
     *
     * @return {QueryIndex} - the same instance of the QueryIndex.
     */
    setFields(fields) {
        this._fields = fields;
        return this;
    }

    /**
     * 
     *
     * @return {Map<string, boolean>}
     */
    getFields() {
        return this._fields;
    }

    /** Private methods */

    /**
     * @ignore
     */
    async _write(communicator, buffer) {
        BinaryCommunicator.writeString(buffer, this._name);
        buffer.writeByte(this._type);
        buffer.writeInteger(this._inlineSize);
        // write fields
        const length = this._fields ? this._fields.size : 0;
        buffer.writeInteger(length);
        if (length > 0) {
            for (let [key, value] of this._fields.entries()) {
                BinaryCommunicator.writeString(buffer, key);
                buffer.writeBoolean(value);
            }
        }
    }

    /**
     * @ignore
     */
    async _read(communicator, buffer) {
        this._name = await communicator.readObject(buffer);
        this._type = buffer.readByte();
        this._inlineSize = buffer.readInteger();
        // read fields
        const length = buffer.readInteger(buffer);
        this._fields = new Map();
        if (length > 0) {
            let res;
            for (let i = 0; i < length; i++) {
                this._fields.set(await communicator.readObject(buffer), buffer.readBoolean());
            }
        }
    }
}

const PROP_NAME = 0;
const PROP_CACHE_MODE = 1;
const PROP_ATOMICITY_MODE = 2;
const PROP_BACKUPS = 3;
const PROP_WRITE_SYNCHRONIZATION_MODE = 4;
const PROP_COPY_ON_READ = 5;
const PROP_READ_FROM_BACKUP = 6;
const PROP_DATA_REGION_NAME = 100;
const PROP_IS_ONHEAP_CACHE_ENABLED = 101;
const PROP_QUERY_ENTITY = 200;
const PROP_QUERY_PARALLELISM = 201;
const PROP_QUERY_DETAIL_METRICS_SIZE = 202;
const PROP_SQL_SCHEMA = 203;
const PROP_SQL_INDEX_INLINE_MAX_SIZE = 204;
const PROP_SQL_ESCAPE_ALL = 205;
const PROP_MAX_QUERY_ITERATORS = 206;
const PROP_REBALANCE_MODE = 300;
const PROP_REBALANCE_DELAY = 301;
const PROP_REBALANCE_TIMEOUT = 302;
const PROP_REBALANCE_BATCH_SIZE = 303;
const PROP_REBALANCE_BATCHES_PREFETCH_COUNT = 304;
const PROP_REBALANCE_ORDER = 305;
const PROP_REBALANCE_THROTTLE = 306;
const PROP_GROUP_NAME = 400;
const PROP_CACHE_KEY_CONFIGURATION = 401;
const PROP_DEFAULT_LOCK_TIMEOUT = 402;
const PROP_MAX_CONCURRENT_ASYNC_OPS = 403;
const PROP_PARTITION_LOSS_POLICY = 404;
const PROP_EAGER_TTL = 405;
const PROP_STATISTICS_ENABLED = 406;

const PROP_TYPES = Object.freeze({
    [PROP_NAME] : BinaryUtils.TYPE_CODE.STRING,
    [PROP_CACHE_MODE] : BinaryUtils.TYPE_CODE.INTEGER,
    [PROP_ATOMICITY_MODE] : BinaryUtils.TYPE_CODE.INTEGER,
    [PROP_BACKUPS] : BinaryUtils.TYPE_CODE.INTEGER,
    [PROP_WRITE_SYNCHRONIZATION_MODE] : BinaryUtils.TYPE_CODE.INTEGER,
    [PROP_COPY_ON_READ] : BinaryUtils.TYPE_CODE.BOOLEAN,
    [PROP_READ_FROM_BACKUP] : BinaryUtils.TYPE_CODE.BOOLEAN,
    [PROP_DATA_REGION_NAME] : BinaryUtils.TYPE_CODE.STRING,
    [PROP_IS_ONHEAP_CACHE_ENABLED] : BinaryUtils.TYPE_CODE.BOOLEAN,
    [PROP_QUERY_ENTITY] : new ObjectArrayType(new ComplexObjectType(new QueryEntity())),
    [PROP_QUERY_PARALLELISM] : BinaryUtils.TYPE_CODE.INTEGER,
    [PROP_QUERY_DETAIL_METRICS_SIZE] : BinaryUtils.TYPE_CODE.INTEGER,
    [PROP_SQL_SCHEMA] : BinaryUtils.TYPE_CODE.STRING,
    [PROP_SQL_INDEX_INLINE_MAX_SIZE] : BinaryUtils.TYPE_CODE.INTEGER,
    [PROP_SQL_ESCAPE_ALL] : BinaryUtils.TYPE_CODE.BOOLEAN,
    [PROP_MAX_QUERY_ITERATORS] : BinaryUtils.TYPE_CODE.INTEGER,
    [PROP_REBALANCE_MODE] : BinaryUtils.TYPE_CODE.INTEGER,
    [PROP_REBALANCE_DELAY] : BinaryUtils.TYPE_CODE.LONG,
    [PROP_REBALANCE_TIMEOUT] : BinaryUtils.TYPE_CODE.LONG,
    [PROP_REBALANCE_BATCH_SIZE] : BinaryUtils.TYPE_CODE.INTEGER,
    [PROP_REBALANCE_BATCHES_PREFETCH_COUNT] : BinaryUtils.TYPE_CODE.LONG,
    [PROP_REBALANCE_ORDER] : BinaryUtils.TYPE_CODE.INTEGER,
    [PROP_REBALANCE_THROTTLE] : BinaryUtils.TYPE_CODE.LONG,
    [PROP_GROUP_NAME] : BinaryUtils.TYPE_CODE.STRING,
    [PROP_CACHE_KEY_CONFIGURATION] : new ObjectArrayType(new ComplexObjectType(new CacheKeyConfiguration())),
    [PROP_DEFAULT_LOCK_TIMEOUT] : BinaryUtils.TYPE_CODE.LONG,
    [PROP_MAX_CONCURRENT_ASYNC_OPS] : BinaryUtils.TYPE_CODE.INTEGER,
    [PROP_PARTITION_LOSS_POLICY] : BinaryUtils.TYPE_CODE.INTEGER,
    [PROP_EAGER_TTL] : BinaryUtils.TYPE_CODE.BOOLEAN,
    [PROP_STATISTICS_ENABLED] : BinaryUtils.TYPE_CODE.BOOLEAN
});

/**
 * 
 * @typedef CacheConfiguration.CACHE_ATOMICITY_MODE
 * @enum
 * @readonly
 * @property TRANSACTIONAL 0
 * @property ATOMIC 1
 */
const CACHE_ATOMICITY_MODE = Object.freeze({
    TRANSACTIONAL : 0,
    ATOMIC : 1
});

/**
 * 
 * @typedef CacheConfiguration.CACHE_MODE
 * @enum
 * @readonly
 * @property LOCAL 0
 * @property REPLICATED 1
 * @property PARTITIONED 2
 */
const CACHE_MODE = Object.freeze({
    LOCAL : 0,
    REPLICATED : 1,
    PARTITIONED : 2
});

/**
 * 
 * @typedef CacheConfiguration.PARTITION_LOSS_POLICY
 * @enum
 * @readonly
 * @property READ_ONLY_SAFE 0
 * @property READ_ONLY_ALL 1
 * @property READ_WRITE_SAFE 2
 * @property READ_WRITE_ALL 3
 * @property IGNORE 4
 */
const PARTITION_LOSS_POLICY = Object.freeze({
    READ_ONLY_SAFE : 0,
    READ_ONLY_ALL : 1,
    READ_WRITE_SAFE : 2,
    READ_WRITE_ALL : 3,
    IGNORE : 4
});

/**
 * 
 * @typedef CacheConfiguration.REABALANCE_MODE
 * @enum
 * @readonly
 * @property SYNC 0
 * @property ASYNC 1
 * @property NONE 2
 */
const REABALANCE_MODE = Object.freeze({
    SYNC : 0,
    ASYNC : 1,
    NONE : 2
});

/**
 * 
 * @typedef CacheConfiguration.WRITE_SYNCHRONIZATION_MODE
 * @enum
 * @readonly
 * @property FULL_SYNC 0
 * @property FULL_ASYNC 1
 * @property PRIMARY_SYNC 2
 */
const WRITE_SYNCHRONIZATION_MODE = Object.freeze({
    FULL_SYNC : 0,
    FULL_ASYNC : 1,
    PRIMARY_SYNC : 2
});

/**
 * Class representing Ignite cache configuration on a server.
 *
 * All configuration settings are optional and have defaults which are defined on a server side.
 *
 * See Apache Ignite documentation for details of every configuration setting. 
 */
class CacheConfiguration {

    /**
     * Public constructor.
     *
     * @return {CacheConfiguration} - new CacheConfiguration instance.
     */
    constructor() {
        this._properties = new Map();
    }

    static get CACHE_ATOMICITY_MODE() {
        return CACHE_ATOMICITY_MODE;
    }

    static get CACHE_MODE() {
        return CACHE_MODE;
    }

    static get PARTITION_LOSS_POLICY() {
        return PARTITION_LOSS_POLICY;
    }

    static get REABALANCE_MODE() {
        return REABALANCE_MODE;
    }

    static get WRITE_SYNCHRONIZATION_MODE() {
        return WRITE_SYNCHRONIZATION_MODE;
    }

    /**
     *
     *
     * @param {CacheConfiguration.CACHE_ATOMICITY_MODE} atomicityMode
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     *
     * @throws {IgniteClientError} if error.
     */
    setAtomicityMode(atomicityMode) {
        ArgumentChecker.hasValueFrom(atomicityMode, 'atomicityMode', false, CACHE_ATOMICITY_MODE);
        this._properties.set(PROP_ATOMICITY_MODE, atomicityMode);
        return this;
    }

    /**
     *
     *
     * @return {CacheConfiguration.CACHE_ATOMICITY_MODE}
     */
    getAtomicityMode() {
        return this._properties.get(PROP_ATOMICITY_MODE);
    }

    /**
     *
     *
     * @param {number} backups
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setBackups(backups) {
        this._properties.set(PROP_BACKUPS, backups);
        return this;
    }

    /**
     *
     *
     * @return {number}
     */
    getBackups() {
        return this._properties.get(PROP_BACKUPS);
    }

    /**
     *
     *
     * @param {CacheConfiguration.CACHE_MODE} cacheMode
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     *
     * @throws {IgniteClientError} if error.
     */
    setCacheMode(cacheMode) {
        ArgumentChecker.hasValueFrom(cacheMode, 'cacheMode', false, CACHE_MODE);
        this._properties.set(PROP_CACHE_MODE, cacheMode);
        return this;
    }

    /**
     *
     *
     * @return {CacheConfiguration.CACHE_MODE}
     */
    getCacheMode() {
        return this._properties.get(PROP_CACHE_MODE);
    }

    /**
     *
     *
     * @param {boolean} copyOnRead
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setCopyOnRead(copyOnRead) {
        this._properties.set(PROP_COPY_ON_READ, copyOnRead);
        return this;
    }

    /**
     *
     *
     * @return {boolean}
     */
    getCopyOnRead() {
        return this._properties.get(PROP_COPY_ON_READ);
    }

    /**
     *
     *
     * @param {string} dataRegionName
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setDataRegionName(dataRegionName) {
        this._properties.set(PROP_DATA_REGION_NAME, dataRegionName);
        return this;
    }

    /**
     *
     *
     * @return {string}
     */
    getDataRegionName() {
        return this._properties.get(PROP_DATA_REGION_NAME);
    }

    /**
     *
     *
     * @param {boolean} eagerTtl
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setEagerTtl(eagerTtl) {
        this._properties.set(PROP_EAGER_TTL, eagerTtl);
        return this;
    }

    /**
     *
     *
     * @return {boolean}
     */
    getEagerTtl() {
        return this._properties.get(PROP_EAGER_TTL);
    }

    /**
     *
     *
     * @param {boolean} statisticsEnabled
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setStatisticsEnabled(statisticsEnabled) {
        this._properties.set(PROP_STATISTICS_ENABLED, statisticsEnabled);
        return this;
    }

    /**
     *
     *
     * @return {boolean}
     */
    getStatisticsEnabled() {
        return this._properties.get(PROP_STATISTICS_ENABLED);
    }

    /**
     *
     *
     * @param {string} groupName
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setGroupName(groupName) {
        this._properties.set(PROP_GROUP_NAME, groupName);
        return this;
    }

    /**
     *
     *
     * @return {string}
     */
    getGroupName() {
        return this._properties.get(PROP_GROUP_NAME);
    }

    /**
     *
     *
     * @param {number} lockTimeout
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setDefaultLockTimeout(lockTimeout) {
        this._properties.set(PROP_DEFAULT_LOCK_TIMEOUT, lockTimeout);
        return this;
    }

    /**
     *
     *
     * @return {number}
     */
    getDefaultLockTimeout() {
        return this._properties.get(PROP_DEFAULT_LOCK_TIMEOUT);
    }

    /**
     *
     *
     * @param {number} maxConcurrentAsyncOperations
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setMaxConcurrentAsyncOperations(maxConcurrentAsyncOperations) {
        this._properties.set(PROP_MAX_CONCURRENT_ASYNC_OPS, maxConcurrentAsyncOperations);
        return this;
    }

    /**
     *
     *
     * @return {number}
     */
    getMaxConcurrentAsyncOperations() {
        return this._properties.get(PROP_MAX_CONCURRENT_ASYNC_OPS);
    }

    /**
     *
     *
     * @param {number} maxQueryIterators
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setMaxQueryIterators(maxQueryIterators) {
        this._properties.set(PROP_MAX_QUERY_ITERATORS, maxQueryIterators);
        return this;
    }

    /**
     *
     *
     * @return {number}
     */
    getMaxQueryIterators() {
        return this._properties.get(PROP_MAX_QUERY_ITERATORS);
    }

    /**
     *
     *
     * @param {boolean} isOnheapCacheEnabled
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setIsOnheapCacheEnabled(isOnheapCacheEnabled) {
        this._properties.set(PROP_IS_ONHEAP_CACHE_ENABLED, isOnheapCacheEnabled);
        return this;
    }

    /**
     *
     *
     * @return {boolean}
     */
    getIsOnheapCacheEnabled() {
        return this._properties.get(PROP_IS_ONHEAP_CACHE_ENABLED);
    }

    /**
     *
     *
     * @param {CacheConfiguration.PARTITION_LOSS_POLICY} partitionLossPolicy
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     *
     * @throws {IgniteClientError} if error.
     */
    setPartitionLossPolicy(partitionLossPolicy) {
        ArgumentChecker.hasValueFrom(partitionLossPolicy, 'partitionLossPolicy', false, PARTITION_LOSS_POLICY);
        this._properties.set(PROP_PARTITION_LOSS_POLICY, partitionLossPolicy);
        return this;
    }

    /**
     *
     *
     * @return {CacheConfiguration.PARTITION_LOSS_POLICY}
     */
    getPartitionLossPolicy() {
        return this._properties.get(PROP_PARTITION_LOSS_POLICY);
    }

    /**
     *
     *
     * @param {number} queryDetailMetricsSize
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setQueryDetailMetricsSize(queryDetailMetricsSize) {
        this._properties.set(PROP_QUERY_DETAIL_METRICS_SIZE, queryDetailMetricsSize);
        return this;
    }

    /**
     *
     *
     * @return {number}
     */
    getQueryDetailMetricsSize() {
        return this._properties.get(PROP_QUERY_DETAIL_METRICS_SIZE);
    }

    /**
     *
     *
     * @param {number} queryParallelism
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setQueryParallelism(queryParallelism) {
        this._properties.set(PROP_QUERY_PARALLELISM, queryParallelism);
        return this;
    }

    /**
     *
     *
     * @return {number}
     */
    getQueryParallelism() {
        return this._properties.get(PROP_QUERY_PARALLELISM);
    }

    /**
     *
     *
     * @param {boolean} readFromBackup
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setReadFromBackup(readFromBackup) {
        this._properties.set(PROP_READ_FROM_BACKUP, readFromBackup);
        return this;
    }

    /**
     *
     *
     * @return {boolean}
     */
    getReadFromBackup() {
        return this._properties.get(PROP_READ_FROM_BACKUP);
    }

    /**
     *
     *
     * @param {number} rebalanceBatchSize
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setRebalanceBatchSize(rebalanceBatchSize) {
        this._properties.set(PROP_REBALANCE_BATCH_SIZE, rebalanceBatchSize);
        return this;
    }

    /**
     *
     *
     * @return {number}
     */
    getRebalanceBatchSize() {
        return this._properties.get(PROP_REBALANCE_BATCH_SIZE);
    }

    /**
     *
     *
     * @param {number} rebalanceBatchesPrefetchCount
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setRebalanceBatchesPrefetchCount(rebalanceBatchesPrefetchCount) {
        this._properties.set(PROP_REBALANCE_BATCHES_PREFETCH_COUNT, rebalanceBatchesPrefetchCount);
        return this;
    }

    /**
     *
     *
     * @return {number}
     */
    getRebalanceBatchesPrefetchCount() {
        return this._properties.get(PROP_REBALANCE_BATCHES_PREFETCH_COUNT);
    }

    /**
     *
     *
     * @param {number} rebalanceDelay
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setRebalanceDelay(rebalanceDelay) {
        this._properties.set(PROP_REBALANCE_DELAY, rebalanceDelay);
        return this;
    }

    /**
     *
     *
     * @return {number}
     */
    getRebalanceDelay() {
        return this._properties.get(PROP_REBALANCE_DELAY);
    }

    /**
     *
     *
     * @param {CacheConfiguration.REABALANCE_MODE} rebalanceMode
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     *
     * @throws {IgniteClientError} if error.
     */
    setRebalanceMode(rebalanceMode) {
        ArgumentChecker.hasValueFrom(rebalanceMode, 'rebalanceMode', false, REABALANCE_MODE);
        this._properties.set(PROP_REBALANCE_MODE, rebalanceMode);
        return this;
    }

    /**
     *
     *
     * @return {CacheConfiguration.REABALANCE_MODE}
     */
    getRebalanceMode() {
        return this._properties.get(PROP_REBALANCE_MODE);
    }

    /**
     *
     *
     * @param {number} rebalanceOrder
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setRebalanceOrder(rebalanceOrder) {
        this._properties.set(PROP_REBALANCE_ORDER, rebalanceOrder);
        return this;
    }

    /**
     *
     *
     * @return {number}
     */
    getRebalanceOrder() {
        return this._properties.get(PROP_REBALANCE_ORDER);
    }

    /**
     *
     *
     * @param {number} rebalanceThrottle
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setRebalanceThrottle(rebalanceThrottle) {
        this._properties.set(PROP_REBALANCE_THROTTLE, rebalanceThrottle);
        return this;
    }

    /**
     *
     *
     * @return {number}
     */
    getRebalanceThrottle() {
        return this._properties.get(PROP_REBALANCE_THROTTLE);
    }

    /**
     *
     *
     * @param {number} rebalanceTimeout
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setRebalanceTimeout(rebalanceTimeout) {
        this._properties.set(PROP_REBALANCE_TIMEOUT, rebalanceTimeout);
        return this;
    }

    /**
     *
     *
     * @return {number}
     */
    getRebalanceTimeout() {
        return this._properties.get(PROP_REBALANCE_TIMEOUT);
    }

    /**
     *
     *
     * @param {boolean} sqlEscapeAll
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setSqlEscapeAll(sqlEscapeAll) {
        this._properties.set(PROP_SQL_ESCAPE_ALL, sqlEscapeAll);
        return this;
    }

    /**
     *
     *
     * @return {boolean}
     */
    getSqlEscapeAll() {
        return this._properties.get(PROP_SQL_ESCAPE_ALL);
    }

    /**
     *
     *
     * @param {number} sqlIndexInlineMaxSize
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setSqlIndexInlineMaxSize(sqlIndexInlineMaxSize) {
        this._properties.set(PROP_SQL_INDEX_INLINE_MAX_SIZE, sqlIndexInlineMaxSize);
        return this;
    }

    /**
     *
     *
     * @return {number}
     */
    getSqlIndexInlineMaxSize() {
        return this._properties.get(PROP_SQL_INDEX_INLINE_MAX_SIZE);
    }

    /**
     *
     *
     * @param {string} sqlSchema
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setSqlSchema(sqlSchema) {
        this._properties.set(PROP_SQL_SCHEMA, sqlSchema);
        return this;
    }

    /**
     *
     *
     * @return {string}
     */
    getSqlSchema() {
        return this._properties.get(PROP_SQL_SCHEMA);
    }

    /**
     *
     *
     * @param {CacheConfiguration.WRITE_SYNCHRONIZATION_MODE} writeSynchronizationMode
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     *
     * @throws {IgniteClientError} if error.
     */
    setWriteSynchronizationMode(writeSynchronizationMode) {
        ArgumentChecker.hasValueFrom(writeSynchronizationMode, 'writeSynchronizationMode', false, WRITE_SYNCHRONIZATION_MODE);
        this._properties.set(PROP_WRITE_SYNCHRONIZATION_MODE, writeSynchronizationMode);
        return this;
    }

    /**
     *
     *
     * @return {CacheConfiguration.WRITE_SYNCHRONIZATION_MODE}
     */
    getWriteSynchronizationMode() {
        return this._properties.get(PROP_WRITE_SYNCHRONIZATION_MODE);
    }

    /**
     * 
     *
     * @param {...CacheKeyConfiguration} keyConfigurations
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     *
     * @throws {IgniteClientError} if error.
     */
    setKeyConfigurations(...keyConfigurations) {
        ArgumentChecker.hasType(keyConfigurations, 'keyConfigurations', true, CacheKeyConfiguration);
        this._properties.set(PROP_CACHE_KEY_CONFIGURATION, keyConfigurations);
        return this;
    }

    /**
     * 
     *
     * @return {Array<CacheKeyConfiguration>}
     */
    getKeyConfigurations() {
        return this._properties.get(PROP_CACHE_KEY_CONFIGURATION);
    }

    /**
     * 
     *
     * @param {...QueryEntity} queryEntities
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     *
     * @throws {IgniteClientError} if error.
     */
    setQueryEntities(...queryEntities) {
        ArgumentChecker.hasType(queryEntities, 'queryEntities', true, QueryEntity);
        this._properties.set(PROP_QUERY_ENTITY, queryEntities);
        return this;
    }

    /**
     * 
     *
     * @return {Array<QueryEntity>}
     */
    getQueryEntities() {
        return this._properties.get(PROP_QUERY_ENTITY);
    }

    /** Private methods */

    /**
     * @ignore
     */
    async _write(communicator, buffer, name) {
        this._properties.set(PROP_NAME, name);

        const startPos = buffer.position;
        buffer.position = buffer.position +
            BinaryUtils.getSize(BinaryUtils.TYPE_CODE.INTEGER) +
            BinaryUtils.getSize(BinaryUtils.TYPE_CODE.SHORT);

        for (let [propertyCode, property] of this._properties) {
            await this._writeProperty(communicator, buffer, propertyCode, property);
        }

        const length = buffer.position - startPos;
        buffer.position = startPos;

        buffer.writeInteger(length);
        buffer.writeShort(this._properties.size);
    }

    /**
     * @ignore
     */
    async _writeProperty(communicator, buffer, propertyCode, property) {
        buffer.writeShort(propertyCode);
        const propertyType = PROP_TYPES[propertyCode];
        switch (BinaryUtils.getTypeCode(propertyType)) {
            case BinaryUtils.TYPE_CODE.INTEGER:
            case BinaryUtils.TYPE_CODE.LONG:
            case BinaryUtils.TYPE_CODE.BOOLEAN:
                await communicator.writeObject(buffer, property, propertyType, false);
                return;
            case BinaryUtils.TYPE_CODE.STRING:
                await communicator.writeObject(buffer, property, propertyType);
                return;
            case BinaryUtils.TYPE_CODE.OBJECT_ARRAY:
                const length = property ? property.length : 0;
                buffer.writeInteger(length);
                for (let prop of property) {
                    await prop._write(communicator, buffer);
                }
                return;
            default:
                throw Errors.IgniteClientError.internalError();
        }
    }

    /**
     * @ignore
     */
    async _read(communicator, buffer) {
        // length
        buffer.readInteger();
        await this._readProperty(communicator, buffer, PROP_ATOMICITY_MODE);
        await this._readProperty(communicator, buffer, PROP_BACKUPS);
        await this._readProperty(communicator, buffer, PROP_CACHE_MODE);
        await this._readProperty(communicator, buffer, PROP_COPY_ON_READ);
        await this._readProperty(communicator, buffer, PROP_DATA_REGION_NAME);
        await this._readProperty(communicator, buffer, PROP_EAGER_TTL);
        await this._readProperty(communicator, buffer, PROP_STATISTICS_ENABLED);
        await this._readProperty(communicator, buffer, PROP_GROUP_NAME);
        await this._readProperty(communicator, buffer, PROP_DEFAULT_LOCK_TIMEOUT);
        await this._readProperty(communicator, buffer, PROP_MAX_CONCURRENT_ASYNC_OPS);
        await this._readProperty(communicator, buffer, PROP_MAX_QUERY_ITERATORS);
        await this._readProperty(communicator, buffer, PROP_NAME);
        await this._readProperty(communicator, buffer, PROP_IS_ONHEAP_CACHE_ENABLED);
        await this._readProperty(communicator, buffer, PROP_PARTITION_LOSS_POLICY);
        await this._readProperty(communicator, buffer, PROP_QUERY_DETAIL_METRICS_SIZE);
        await this._readProperty(communicator, buffer, PROP_QUERY_PARALLELISM);
        await this._readProperty(communicator, buffer, PROP_READ_FROM_BACKUP);
        await this._readProperty(communicator, buffer, PROP_REBALANCE_BATCH_SIZE);
        await this._readProperty(communicator, buffer, PROP_REBALANCE_BATCHES_PREFETCH_COUNT);
        await this._readProperty(communicator, buffer, PROP_REBALANCE_DELAY);
        await this._readProperty(communicator, buffer, PROP_REBALANCE_MODE);
        await this._readProperty(communicator, buffer, PROP_REBALANCE_ORDER);
        await this._readProperty(communicator, buffer, PROP_REBALANCE_THROTTLE);
        await this._readProperty(communicator, buffer, PROP_REBALANCE_TIMEOUT);
        await this._readProperty(communicator, buffer, PROP_SQL_ESCAPE_ALL);
        await this._readProperty(communicator, buffer, PROP_SQL_INDEX_INLINE_MAX_SIZE);
        await this._readProperty(communicator, buffer, PROP_SQL_SCHEMA);
        await this._readProperty(communicator, buffer, PROP_WRITE_SYNCHRONIZATION_MODE);
        await this._readProperty(communicator, buffer, PROP_CACHE_KEY_CONFIGURATION);
        await this._readProperty(communicator, buffer, PROP_QUERY_ENTITY);
    }

    /**
     * @ignore
     */
    async _readProperty(communicator, buffer, propertyCode) {
        const propertyType = PROP_TYPES[propertyCode];
        switch (BinaryUtils.getTypeCode(propertyType)) {
            case BinaryUtils.TYPE_CODE.INTEGER:
            case BinaryUtils.TYPE_CODE.LONG:
            case BinaryUtils.TYPE_CODE.BOOLEAN:
                this._properties.set(propertyCode, await communicator._readTypedObject(buffer, propertyType));
                return;
            case BinaryUtils.TYPE_CODE.STRING:
                this._properties.set(propertyCode, await communicator.readObject(buffer, propertyType));
                return;
            case BinaryUtils.TYPE_CODE.OBJECT_ARRAY:
                const length = buffer.readInteger();
                if (length > 0) {
                    const properties = new Array(length);
                    for (let i = 0; i < length; i++) {
                        const property = new propertyType._elementType._objectConstructor();
                        await property._read(communicator, buffer);
                        properties[i] = property;
                    }
                    this._properties.set(propertyCode, properties);
                }
                return;
            default:
                throw Errors.IgniteClientError.internalError();
        }
    }
}

module.exports = CacheConfiguration;
module.exports.QueryEntity = QueryEntity;
module.exports.QueryField = QueryField;
module.exports.QueryIndex = QueryIndex;
module.exports.CacheKeyConfiguration = CacheKeyConfiguration;
