/*
 * 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.
 */

package org.apache.ignite.client;

import java.util.concurrent.Executor;
import java.util.concurrent.ForkJoinPool;
import java.util.function.Function;
import org.apache.ignite.lang.LoggerFactory;
import org.jetbrains.annotations.Nullable;

/**
 * Ignite client configuration.
 */
public interface IgniteClientConfiguration {
    /** Default port. */
    int DFLT_PORT = 10800;

    /** Default port range. */
    int DFLT_PORT_RANGE = 100;

    /** Default socket connect timeout, in milliseconds. */
    int DFLT_CONNECT_TIMEOUT = 5000;

    /** Default heartbeat interval, in milliseconds. */
    int DFLT_HEARTBEAT_INTERVAL = 30_000;

    /** Default operation retry limit. */
    int DFLT_RETRY_LIMIT = 5;

    /** Default reconnect throttling period. */
    long DFLT_RECONNECT_THROTTLING_PERIOD = 30_000L;

    /** Default reconnect throttling retries. */
    int DFLT_RECONNECT_THROTTLING_RETRIES = 3;

    /**
     * Gets the address finder.
     *
     * @return Address finder.
     */
    IgniteClientAddressFinder addressesFinder();

    /**
     * Gets the addresses of Ignite server nodes within a cluster. An address can be an IP address or a hostname, with or without port. If
     * port is not set then Ignite will generate multiple addresses for default port range. See {@link IgniteClientConfiguration#DFLT_PORT},
     * {@link IgniteClientConfiguration#DFLT_PORT_RANGE}.
     *
     * @return Addresses.
     */
    String[] addresses();

    /**
     * Gets the retry policy. When a request fails due to a connection error, and multiple server connections
     * are available, Ignite will retry the request if the specified policy allows it.
     *
     * @return Retry policy.
     */
    @Nullable RetryPolicy retryPolicy();

    /**
     * Gets the socket connect timeout, in milliseconds.
     *
     * @return Socket connect timeout, in milliseconds.
     */
    long connectTimeout();

    /**
     * Gets the reconnect throttling period, in milliseconds.
     *
     * @return Reconnect period for throttling, in milliseconds.
     */
    long reconnectThrottlingPeriod();

    /**
     * Gets the reconnect throttling retries.
     *
     * @return Reconnect throttling retries.
     */
    int reconnectThrottlingRetries();

    /**
     * Gets the async continuation executor.
     *
     * <p>When <code>null</code> (default), {@link ForkJoinPool#commonPool()} is used.
     *
     * <p>When async client operation completes, corresponding {@link java.util.concurrent.CompletableFuture} continuations
     * (such as {@link java.util.concurrent.CompletableFuture#thenApply(Function)}) will be invoked using this executor.
     *
     * <p>Server responses are handled by a dedicated network thread. To ensure optimal performance,
     * this thread should not perform any extra work, so user-defined continuations are offloaded to the specified executor.
     *
     * @return Executor for async continuations.
     */
    @Nullable Executor asyncContinuationExecutor();

    /**
     * Gets the heartbeat message interval, in milliseconds. Default is <code>30_000</code>.
     *
     * <p>When server-side idle timeout is not zero, effective heartbeat
     * interval is set to <code>min(heartbeatInterval, idleTimeout / 3)</code>.
     *
     * <p>When thin client connection is idle (no operations are performed), heartbeat messages are sent periodically
     * to keep the connection alive and detect potential half-open state.
     *
     * @return Heartbeat interval.
     */
    public long heartbeatInterval();

    /**
     * Returns the logger factory. This factory will be used to create a logger instance when needed.
     *
     * <p>When {@code null} (default), {@link System#getLogger} is used.
     *
     * @return Configured logger factory.
     */
    @Nullable LoggerFactory loggerFactory();
}
