/*
 * Copyright 2020-2021 the original author or authors.
 *
 * 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
 *
 *      https://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.
 */

package io.lettuce.core.api.coroutines

import io.lettuce.core.ExperimentalLettuceCoroutinesApi
import io.lettuce.core.KillArgs
import io.lettuce.core.TrackingArgs
import io.lettuce.core.UnblockType
import io.lettuce.core.protocol.CommandType
import java.util.*

/**
 * Coroutine executed commands for Server Control.
 *
 * @param <K> Key type.
 * @param <V> Value type.
 * @author Mikhael Sokolov
 * @since 6.0
 * @generated by io.lettuce.apigenerator.CreateKotlinCoroutinesApi
 */
@ExperimentalLettuceCoroutinesApi
interface RedisServerCoroutinesCommands<K : Any, V : Any> {

    /**
     * Asynchronously rewrite the append-only file.
     *
     * @return String simple-string-reply always `OK`.
     */
    suspend fun bgrewriteaof(): String?

    /**
     * Asynchronously save the dataset to disk.
     *
     * @return String simple-string-reply.
     */
    suspend fun bgsave(): String?

    /**
     * Control tracking of keys in the context of server-assisted client cache invalidation.
     *
     * @param enabled @code true} to enable key tracking.
     * @return String simple-string-reply `OK`.
     * @since 6.0
     */
    suspend fun clientCaching(enabled: Boolean): String?

    /**
     * Get the current connection name.
     *
     * @return K bulk-string-reply The connection name, or a null bulk reply if no name is set.
     */
    suspend fun clientGetname(): K?

    /**
     * Returns the client ID we are redirecting our tracking notifications to.
     *
     * @return the ID of the client we are redirecting the notifications to. The command returns -1 if client tracking is not
     *         enabled, or 0 if client tracking is enabled but we are not redirecting the notifications to any client.
     * @since 6.0
     */
    suspend fun clientGetredir(): Long?

    /**
     * Get the id of the current connection.
     *
     * @return Long The command just returns the ID of the current connection.
     * @since 5.3
     */
    suspend fun clientId(): Long?

    /**
     * Kill the connection of a client identified by ip:port.
     *
     * @param addr ip:port.
     * @return String simple-string-reply `OK` if the connection exists and has been closed.
     */
    suspend fun clientKill(addr: String): String?

    /**
     * Kill connections of clients which are filtered by `killArgs`.
     *
     * @param killArgs args for the kill operation.
     * @return Long integer-reply number of killed connections.
     */
    suspend fun clientKill(killArgs: KillArgs): Long?

    /**
     * Get the list of client connections.
     *
     * @return String bulk-string-reply a unique string, formatted as follows: One client connection per line (separated by LF),
     *         each line is composed of a succession of property=value fields separated by a space character.
     */
    suspend fun clientList(): String?

    /**
     * Stop processing commands from clients for some time.
     *
     * @param timeout the timeout value in milliseconds.
     * @return String simple-string-reply The command returns OK or an error if the timeout is invalid.
     */
    suspend fun clientPause(timeout: Long): String?

    /**
     * Set the current connection name.
     *
     * @param name the client name.
     * @return simple-string-reply `OK` if the connection name was successfully set.
     */
    suspend fun clientSetname(name: K): String?

    /**
     * Enables the tracking feature of the Redis server, that is used for server assisted client side caching. Tracking messages
     * are either available when using the RESP3 protocol or through Pub/Sub notification when using RESP2.
     *
     * @param args for the CLIENT TRACKING operation.
     * @return String simple-string-reply `OK`.
     * @since 6.0
     */
    suspend fun clientTracking(args: TrackingArgs): String?

    /**
     * Unblock the specified blocked client.
     *
     * @param id the client id.
     * @param type unblock type.
     * @return Long integer-reply number of unblocked connections.
     * @since 5.1
     */
    suspend fun clientUnblock(id: Long, type: UnblockType): Long?

    /**
     * Returns an array reply of details about all Redis commands.
     *
     * @return List<Any> array-reply.
     */
    suspend fun command(): List<Any>

    /**
     * Get total number of Redis commands.
     *
     * @return Long integer-reply of number of total commands in this Redis server.
     */
    suspend fun commandCount(): Long?

    /**
     * Returns an array reply of details about the requested commands.
     *
     * @param commands the commands to query for.
     * @return List<Any> array-reply.
     */
    suspend fun commandInfo(vararg commands: String): List<Any>

    /**
     * Returns an array reply of details about the requested commands.
     *
     * @param commands the commands to query for.
     * @return List<Any> array-reply.
     */
    suspend fun commandInfo(vararg commands: CommandType): List<Any>

    /**
     * Get the value of a configuration parameter.
     *
     * @param parameter name of the parameter.
     * @return Map<String, String> bulk-string-reply.
     */
    suspend fun configGet(parameter: String): Map<String, String>?

    /**
     * Reset the stats returned by INFO.
     *
     * @return String simple-string-reply always `OK`.
     */
    suspend fun configResetstat(): String?

    /**
     * Rewrite the configuration file with the in memory configuration.
     *
     * @return String simple-string-reply `OK` when the configuration was rewritten properly. Otherwise an error is
     *         returned.
     */
    suspend fun configRewrite(): String?

    /**
     * Set a configuration parameter to the given value.
     *
     * @param parameter the parameter name.
     * @param value the parameter value.
     * @return String simple-string-reply: `OK` when the configuration was set properly. Otherwise an error is returned.
     */
    suspend fun configSet(parameter: String, value: String): String?

    /**
     * Return the number of keys in the selected database.
     *
     * @return Long integer-reply.
     */
    suspend fun dbsize(): Long?

    /**
     * Crash and recover.
     *
     * @param delay optional delay in milliseconds.
     * @return String simple-string-reply.
     */
    suspend fun debugCrashAndRecover(delay: Long): String?

    /**
     * Get debugging information about the internal hash-table state.
     *
     * @param db the database number.
     * @return String simple-string-reply.
     */
    suspend fun debugHtstats(db: Int): String?

    /**
     * Get debugging information about a key.
     *
     * @param key the key.
     * @return String simple-string-reply.
     */
    suspend fun debugObject(key: K): String?

    /**
     * Make the server crash: Out of memory.
     *
     * @return nothing, because the server crashes before returning.
     */
    suspend fun debugOom()

    /**
     * Save RDB, clear the database and reload RDB.
     *
     * @return String simple-string-reply The commands returns OK on success.
     */
    suspend fun debugReload(): String?

    /**
     * Restart the server gracefully.
     *
     * @param delay optional delay in milliseconds.
     * @return String simple-string-reply.
     */
    suspend fun debugRestart(delay: Long): String?

    /**
     * Get debugging information about the internal SDS length.
     *
     * @param key the key.
     * @return String simple-string-reply.
     */
    suspend fun debugSdslen(key: K): String?

    /**
     * Make the server crash: Invalid pointer access.
     *
     * @return nothing, because the server crashes before returning.
     */
    suspend fun debugSegfault()

    /**
     * Remove all keys from all databases.
     *
     * @return String simple-string-reply.
     */
    suspend fun flushall(): String?

    /**
     * Remove all keys asynchronously from all databases.
     *
     * @return String simple-string-reply.
     */
    suspend fun flushallAsync(): String?

    /**
     * Remove all keys from the current database.
     *
     * @return String simple-string-reply.
     */
    suspend fun flushdb(): String?

    /**
     * Remove all keys asynchronously from the current database.
     *
     * @return String simple-string-reply.
     */
    suspend fun flushdbAsync(): String?

    /**
     * Get information and statistics about the server.
     *
     * @return String bulk-string-reply as a collection of text lines.
     */
    suspend fun info(): String?

    /**
     * Get information and statistics about the server.
     *
     * @param section the section type: string.
     * @return String bulk-string-reply as a collection of text lines.
     */
    suspend fun info(section: String): String?

    /**
     * Get the UNIX time stamp of the last successful save to disk.
     *
     * @return Date integer-reply an UNIX time stamp.
     */
    suspend fun lastsave(): Date?

    /**
     * Reports the number of bytes that a key and its value require to be stored in RAM.
     *
     * @return memory usage in bytes.
     * @since 5.2
     */
    suspend fun memoryUsage(key: K): Long?

    /**
     * Synchronously save the dataset to disk.
     *
     * @return String simple-string-reply The commands returns OK on success.
     */
    suspend fun save(): String?

    /**
     * Synchronously save the dataset to disk and then shut down the server.
     *
     * @param save @code true} force save operation.
     */
    suspend fun shutdown(save: Boolean)

    /**
     * Make the server a replica of another instance, or promote it as master.
     *
     * @param host the host type: string.
     * @param port the port type: string.
     * @return String simple-string-reply.
     */
    suspend fun slaveof(host: String, port: Int): String?

    /**
     * Promote server as master.
     *
     * @return String simple-string-reply.
     */
    suspend fun slaveofNoOne(): String?

    /**
     * Read the slow log.
     *
     * @return List<Any> deeply nested multi bulk replies.
     */
    suspend fun slowlogGet(): List<Any>

    /**
     * Read the slow log.
     *
     * @param count the count.
     * @return List<Any> deeply nested multi bulk replies.
     */
    suspend fun slowlogGet(count: Int): List<Any>

    /**
     * Obtaining the current length of the slow log.
     *
     * @return Long length of the slow log.
     */
    suspend fun slowlogLen(): Long?

    /**
     * Resetting the slow log.
     *
     * @return String simple-string-reply The commands returns OK on success.
     */
    suspend fun slowlogReset(): String?

    /**
     * Return the current server time.
     *
     * @return List<V> array-reply specifically:
     *
     *         A multi bulk reply containing two elements:
     *
     *         unix time in seconds. microseconds.
     */
    suspend fun time(): List<V>

}

