/*
 * 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';

import BinaryCommunicator from "./internal/BinaryCommunicator";
import ArgumentChecker from "./internal/ArgumentChecker";
import Logger from "./internal/Logger";

import Router from "./internal/Router";
import {IgniteClientConfiguration} from "./IgniteClientConfiguration";
import {CacheConfiguration} from "./CacheConfiguration";
import { CacheClient } from "./CacheClient";
import BinaryUtils from "./internal/BinaryUtils";
import MessageBuffer from "./internal/MessageBuffer";

/**
 * State of Ignite client.
 *
 * @typedef IgniteClient.STATE
 * @enum
 * @readonly
 * @property DISCONNECTED The client is not connected to any Ignite node,
 *     operations with the Ignite server are not allowed.
 *     This is initial state after a client instance creation.
 *     If connect() method is called, the client moves to CONNECTING state.
 * @property CONNECTING The client tries to connect to an Ignite node,
 *     operations with the Ignite server are not allowed.
 *     If disconnect() method is called, the client moves to DISCONNECTED state.
 *     If not possible to connect to any Ignite node, the client moves to DISCONNECTED state.
 *     If connection to an Ignite node is successful, the client moves to CONNECTED state.
 * @property CONNECTED The client is connected to an Ignite node,
 *     all operations with the Ignite server are allowed.
 *     If connection with the Ignite node is lost, the client moves to CONNECTING state.
 *     If disconnect() method is called, the client moves to DISCONNECTED state.
 */
export enum STATE {
    DISCONNECTED = 0,
    CONNECTING = 1,
    CONNECTED = 2
}

export type IgniteClientOnStateChanged = (state: STATE, reason: string) => void;

/**
 * Class representing Ignite client.
 *
 */
export class IgniteClient {

    private _router: Router;

    private _communicator: BinaryCommunicator;

    /**
     * Public constructor.
     *
     * @param {IgniteClientOnStateChanged} [onStateChanged] -
     * callback called everytime when the client has moved to a new state {@link STATE}.
     *
     * @return {IgniteClient} - new IgniteClient instance.
     */
    constructor(onStateChanged: IgniteClientOnStateChanged = null) {
        this._router = new Router(onStateChanged);
        this._communicator = new BinaryCommunicator(this._router);
    }

    static get STATE() {
        return STATE;
    }

    /**
     * Connects the client.
     *
     * Should be called from DISCONNECTED state only.
     * Moves the client to CONNECTING state.
     *
     * @async
     *
     * @param {IgniteClientConfiguration} config - the client configuration.
     *
     * @throws {IllegalStateError} if the client is not in DISCONNECTED {@link IgniteClient.STATE}.
     * @throws {IgniteClientError} if other error.
     */
    async connect(config: IgniteClientConfiguration): Promise<void> {
        ArgumentChecker.notEmpty(config, 'config');
        ArgumentChecker.hasType(config, 'config', false, IgniteClientConfiguration);
        await this._router.connect(this._communicator, config);
    }

    /**
     * Disconnects the client.
     *
     * Moves the client to DISCONNECTED state from any other state.
     * Does nothing if the client already disconnected.
     */
    disconnect() {
        this._router.disconnect();
    }

    /**
     * Creates new cache with the provided name and optional configuration.
     *
     * @async
     *
     * @param {string} name - cache name.
     * @param {CacheConfiguration} [cacheConfig] - cache configuration.
     *
     * @return {Promise<CacheClient>} - new cache client instance for the created cache.
     *
     * @throws {IllegalStateError} if the client is not in CONNECTED {@link IgniteClient.STATE}.
     * @throws {OperationError} if cache with the provided name already exists.
     * @throws {IgniteClientError} if other error.
     */
    async createCache(name, cacheConfig = null) {
        ArgumentChecker.notEmpty(name, 'name');
        ArgumentChecker.hasType(cacheConfig, 'cacheConfig', false, CacheConfiguration);

        await this._communicator.send(
            cacheConfig ?
                BinaryUtils.OPERATION.CACHE_CREATE_WITH_CONFIGURATION :
                BinaryUtils.OPERATION.CACHE_CREATE_WITH_NAME,
            async (payload) => {
                await this._writeCacheNameOrConfig(payload, name, cacheConfig);
            });

        return this._getCache(name, cacheConfig);
    }

    /**
     * Gets existing cache with the provided name
     * or creates new one with the provided name and optional configuration.
     *
     * @async
     *
     * @param {string} name - cache name.
     * @param {CacheConfiguration} [cacheConfig] - cache configuration (ignored if cache
     *   with the provided name already exists).
     *
     * @return {Promise<CacheClient>} - new cache client instance for the existing or created cache.
     *
     * @throws {IllegalStateError} if the client is not in CONNECTED {@link IgniteClient.STATE}.
     * @throws {IgniteClientError} if other error.
     */
    async getOrCreateCache(name, cacheConfig = null): Promise<CacheClient> {
        ArgumentChecker.notEmpty(name, 'name');
        ArgumentChecker.hasType(cacheConfig, 'cacheConfig', false, CacheConfiguration);
        await this._communicator.send(
            cacheConfig ?
                BinaryUtils.OPERATION.CACHE_GET_OR_CREATE_WITH_CONFIGURATION :
                BinaryUtils.OPERATION.CACHE_GET_OR_CREATE_WITH_NAME,
            async (payload) => {
                await this._writeCacheNameOrConfig(payload, name, cacheConfig);
            });
        return this._getCache(name, cacheConfig);
    }

    /**
     * Gets cache client instance of cache with the provided name.
     * The method does not check if the cache with the provided name exists.
     *
     * @param {string} name - cache name.
     *
     * @return {CacheClient} - new cache client instance.
     *
     * @throws {IgniteClientError} if error.
     */
    getCache(name) {
        ArgumentChecker.notEmpty(name, 'name');
        return this._getCache(name);
    }

    /**
     * Destroys cache with the provided name.
     *
     * @async
     *
     * @param {string} name - cache name.
     *
     * @throws {IllegalStateError} if the client is not in CONNECTED {@link IgniteClient.STATE}.
     * @throws {OperationError} if cache with the provided name does not exist.
     * @throws {IgniteClientError} if other error.
     */
    async destroyCache(name) {
        ArgumentChecker.notEmpty(name, 'name');

        const cacheId = CacheClient._calculateId(name);

        await this._communicator.send(
            BinaryUtils.OPERATION.CACHE_DESTROY,
            async (payload) => {
                payload.writeInteger(cacheId);
            });
    }

    /**
     * Returns configuration of cache with the provided name.
     *
     * @async
     *
     * @param {string} name - cache name.
     *
     * @return {Promise<CacheConfiguration>} - cache configuration
     *
     * @throws {IllegalStateError} if the client is not in CONNECTED {@link IgniteClient.STATE}.
     * @throws {OperationError} if cache with the provided name does not exist.
     * @throws {IgniteClientError} if other error.
     */
    async getCacheConfiguration(name) {
        ArgumentChecker.notEmpty(name, 'name');
        let config;
        await this._communicator.send(
            BinaryUtils.OPERATION.CACHE_GET_CONFIGURATION,
            async (payload) => {
                payload.writeInteger(CacheClient._calculateId(name));
                payload.writeByte(0);
            },
            async (payload) => {
                config = new CacheConfiguration();
                await config._read(this._communicator, payload);
            });
        return config;
    }

    /**
     * Gets existing cache names.
     *
     * @async
     *
     * @return {Promise<Array<string>>} - array with the existing cache names.
     *     The array is empty if no caches exist.
     *
     * @throws {IllegalStateError} if the client is not in CONNECTED {@link IgniteClient.STATE}.
     * @throws {IgniteClientError} if other error.
     */
    async cacheNames(): Promise<string[]> {
        let names;
        await this._communicator.send(
            BinaryUtils.OPERATION.CACHE_GET_NAMES,
            null,
            async (payload) => {
                names = await this._communicator.readStringArray(payload);
            });
        return names;
    }

    /**
     * Enables/disables the library debug output (including errors logging).
     * Disabled by default.
     *
     * @param {boolean} value - true to enable, false to disable
     */
    setDebug(value) {
        Logger.debug = value;
    }

    /** Private methods */

    /**
     * @ignore
     */
    _getCache(name: string, cacheConfig: CacheConfiguration = null) {
        return new CacheClient(name, cacheConfig, this._communicator);
    }

    /**
     * @ignore
     */
    async _writeCacheNameOrConfig(buffer: MessageBuffer, name: string, cacheConfig: CacheConfiguration) {
        if (cacheConfig) {
            await cacheConfig._write(this._communicator, buffer, name);
        }
        else {
            BinaryCommunicator.writeString(buffer, name);
        }
    }
}
