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

#pragma once

#ifndef GEODE_POOLFACTORY_H_
#define GEODE_POOLFACTORY_H_

#include <chrono>

#include "Pool.hpp"
#include "internal/chrono/duration.hpp"
#include "internal/geode_globals.hpp"

/**
 * @file
 */

namespace apache {
namespace geode {
namespace client {

class CacheImpl;
class PoolAttributes;
class Pool;

/**
 * This interface provides for the configuration and creation of instances of
 * {@link Pool}.
 * <p>Every pool needs to have at least one {@link #addLocator locator} or
 * {@link #addServer server} added
 * to it. Locators should be added unless direct connections to
 * bridge servers are desired.
 * <p>The setter methods are used to specify
 * non-default values for the other pool properties.
 * <p>Once it is configured {@link #create}
 * will produce an instance.
 * <p>The factory can be restored to its default
 * configuration by calling {@link #reset}.
 * <p>Instances of this interface can be created by calling
 * {@link Cache#getPoolFactory}.
 * <p>
 * If a subscription is going to be made using a pool then subscriptions
 * {@link #setSubscriptionEnabled must be enabled} on the pool.
 * Subscriptions are made using these APIs:
 * <ul>
 * <li>{@link QueryService#newCq}
 * <li>{@link Region#registerKeys}
 * <li>{@link Region#registerAllKeys}
 * <li>{@link Region#registerRegex}
 * </ul>
 *
 */
class APACHE_GEODE_EXPORT PoolFactory {
 public:
  /**
   * The default amount of time which we will wait for a free connection if max
   * connections is set and all of the connections are in use.
   * <p>Current value: <code>10s</code>.
   */
  static const std::chrono::milliseconds DEFAULT_FREE_CONNECTION_TIMEOUT;

  /**
   * The default interval in which the pool will check to see if
   * a connection to a given server should be moved to a different
   * server to improve the load balance.
   * <p>Current value: <code>5min</code>
   */
  static const std::chrono::milliseconds DEFAULT_LOAD_CONDITIONING_INTERVAL;

  /**
   * The default size in bytes of the socket buffer on each connection
   * established.
   * <p>Current value: <code>32768</code>.
   */
  static const int DEFAULT_SOCKET_BUFFER_SIZE = 32768;

  /**
   * The default amount of time to wait for a response from a server.
   * <p>Current value: <code>10s</code>.
   */
  static const std::chrono::milliseconds DEFAULT_READ_TIMEOUT;

  /**
   * The default number of connections to be created initially.
   * <p>Current value: <code>1</code>.
   */
  static const int DEFAULT_MIN_CONNECTIONS = 1;

  /**
   * The default maximum number of connections to be created.
   * <p>Current value: <code>-1</code>.
   */
  static const int DEFAULT_MAX_CONNECTIONS = -1;

  /**
   * The default amount of time to wait for a connection to become idle.
   * <p>Current value: <code>5s</code>.
   */
  static const std::chrono::milliseconds DEFAULT_IDLE_TIMEOUT;

  /**
   * The default number of times to retry an operation after a timeout or
   * exception.
   * <p>Current value: <code>-1</code>.
   */
  static const int DEFAULT_RETRY_ATTEMPTS = -1;

  /**
   * The default frequency, to ping servers.
   * <p>Current value: <code>10s</code>.
   */
  static const std::chrono::milliseconds DEFAULT_PING_INTERVAL;

  /**
   * The default frequency to update the locator list.
   * <p>Current value: <code>5s</code>.
   */
  static const std::chrono::milliseconds DEFAULT_UPDATE_LOCATOR_LIST_INTERVAL;

  /**
   * The default frequency that client statistics are sent to the server.
   * <p>Current value: <code>std::chrono::milliseconds::zero()</code>
   * (disabled).
   */
  static const std::chrono::milliseconds DEFAULT_STATISTIC_INTERVAL;

  /**
   * The default value for whether to establish a server to client subscription.
   * <p>Current value: <code>false</code>.
   */
  static const bool DEFAULT_SUBSCRIPTION_ENABLED = false;

  /**
   * The default redundancy for servers holding subscriptions established by
   * this
   * client.
   * <p>Current value: <code>0</code>.
   */
  static const int DEFAULT_SUBSCRIPTION_REDUNDANCY = 0;

  /**
   * The default amount of time that messages sent from a  server to a client
   * will be tracked. The tracking is done to minimize duplicate events.
   * <p>Current value: <code>900s</code>.
   */
  static const std::chrono::milliseconds
      DEFAULT_SUBSCRIPTION_MESSAGE_TRACKING_TIMEOUT;

  /**
   * The default amount of time to wait before sending an acknowledgement to the
   * server about events received from the subscriptions.
   * <p>Current value: <code>100ms</code>.
   */
  static const std::chrono::milliseconds DEFAULT_SUBSCRIPTION_ACK_INTERVAL;

  /**
   * The default server group.
   * <p>Current value: <code>""</code>.
   */
  static const std::string DEFAULT_SERVER_GROUP;
  /**
   * Whether thread local connection is enabled.
   * <p>Current value: <code>"false"</code>.
   */
  static constexpr bool DEFAULT_THREAD_LOCAL_CONN = false;

  /**
   * Whether client is in multi user secure mode
   * <p>Current value: <code>"false"</code>.
   */
  static constexpr bool DEFAULT_MULTIUSER_SECURE_MODE = false;

  /**
   * The default value for whether to have single hop optimizations enabled.
   * <p>Current value: <code>true</code>.
   */
  static constexpr bool DEFAULT_PR_SINGLE_HOP_ENABLED = true;

  /**
   * Sets the free connection timeout for this pool.
   * If the pool has a max connections setting, operations will block
   * if all of the connections are in use. The free connection timeout
   * specifies how long those operations will block waiting for
   * a free connection before receiving
   * an {@link AllConnectionsInUseException}. If max connections
   * is not set this setting has no effect.
   *
   * @see #setMaxConnections(int)
   *
   * @param connectionTimeout is the connection timeout
   *
   * @return a reference to <code>this</code>
   * @throws IllegalArgumentException if <code>connectionTimeout</code>
   * is less than or equal to <code>std::chrono::milliseconds::zero()</code>.
   */
  PoolFactory& setFreeConnectionTimeout(
      std::chrono::milliseconds connectionTimeout);

  /**
   * Sets the load conditioning interval for this pool.
   * This interval controls how frequently the pool will check to see if
   * a connection to a given server should be moved to a different
   * server to improve the load balance.
   * <p>A value of <code>std::chrono::milliseconds::zero()</code> disables load
   * conditioning.
   *
   * @param loadConditioningInterval is the connection lifetime
   *
   * @return a reference to <code>this</code>
   * @throws IllegalArgumentException if <code>connectionLifetime</code>
   * is less than <code>std::chrono::milliseconds::zero()</code>.
   */
  PoolFactory& setLoadConditioningInterval(
      std::chrono::milliseconds loadConditioningInterval);

  /**
   * Sets the socket buffer size for each connection made in this pool.
   * Large messages can be received and sent faster when this buffer is larger.
   * Larger buffers also optimize the rate at which servers can send events
   * for client subscriptions.
   *
   * @param bufferSize is the size of the socket buffers used for reading and
   * writing on each connection in this pool.
   *
   * @return a reference to <code>this</code>
   * @throws IllegalArgumentException if <code>bufferSize</code>
   * is less than or equal to <code>0</code>.
   */
  PoolFactory& setSocketBufferSize(int bufferSize);

  /**
   * Sets the thread local connections policy for this pool.
   * If <code>true</code> then any time a thread goes to use a connection
   * from this pool it will check a thread local cache and see if it already
   * has a connection in it. If so it will use it. If not it will get one from
   * this pool and cache it in the thread local. This gets rid of thread
   * contention
   * for the connections but increases the number of connections the servers
   * see.
   * <p>If <code>false</code> then connections are returned to the pool as soon
   * as the operation being done with the connection completes. This allows
   * connections to be shared among multiple threads keeping the number of
   * connections down.
   *
   * @param threadLocalConnections if <code>true</code> then enable thread local
   * connections.
   * @return a reference to <code>this</code>
   */
  PoolFactory& setThreadLocalConnections(bool threadLocalConnections);

  /**
   * Sets the duration to wait for a response from a server before timing out
   * the operation and trying another server (if any are available).
   *
   * @param timeout duration to wait for a response from a
   * server
   * @return a reference to <code>this</code>
   * @throws IllegalArgumentException if <code>timeout</code>
   * is less than or equal to <code>std::chrono::milliseconds::zero()</code>.
   */
  PoolFactory& setReadTimeout(std::chrono::milliseconds timeout);

  /**
   * Sets the minimum number of connections to keep available at all times.
   * When the pool is created, it will create this many connections.
   * If <code>0</code> then connections will not be made until an actual
   * operation
   * is done that requires client-to-server communication.
   *
   * @param minConnections is the initial number of connections
   * this pool will create.
   * @return a reference to <code>this</code>
   * @throws IllegalArgumentException if <code>minConnections</code>
   * is less than <code>0</code>.
   */
  PoolFactory& setMinConnections(int minConnections);

  /**
   * Sets the max number of client to server connections that the pool will
   * create. If all of
   * the connections are in use, an operation requiring a client to server
   * connection
   * will block until a connection is available.
   *
   * @see #setFreeConnectionTimeout(int)
   *
   * @param maxConnections is the maximum number of connections in the pool.
   * <code>-1</code> indicates that there is no maximum number of connections
   *
   * @return a reference to <code>this</code>
   * @throws IllegalArgumentException if <code>maxConnections</code>
   * is less than <code>minConnections</code>.
   */
  PoolFactory& setMaxConnections(int maxConnections);

  /**
   * Sets the amount of time a connection can be idle before expiring the
   * connection. If the pool size is greater than the minimum specified by
   * {@link PoolFactory#setMinConnections(int)}, connections which have been
   * idle for longer than the idleTimeout will be closed.
   *
   * @param idleTimeout is the duration that an idle connection
   * should live no less than before expiring, actual time may be longer
   * depending on clock resolution. A duration std::chrono::milliseconds::zero()
   * indicates that connections should never expire.
   * @return a reference to <code>this</code>
   */
  PoolFactory& setIdleTimeout(std::chrono::milliseconds);

  /**
   * Set the number of times to retry a request after timeout/exception.
   * @param retryAttempts is the number of times to retry a request
   * after timeout/exception. -1 indicates that a request should be
   * tried against every available server before failing
   * @return a reference to <code>this</code>
   * @throws IllegalArgumentException if <code>idleTimout</code>
   * is less than <code>0</code>.
   */
  PoolFactory& setRetryAttempts(int retryAttempts);

  /**
   * The frequency with which servers must be pinged to verify that they are
   * still alive.
   * Each server will be sent a ping every <code>pingInterval</code> if there
   * has not
   * been any other communication with the server.
   *
   * These pings are used by the server to monitor the health of
   * the client. Make sure that the <code>pingInterval</code> is less than the
   * maximum time between pings allowed by the bridge server.
   *
   * @param pingInterval is the amount of time  between pings.
   * @return a reference to <code>this</code>
   * @throws IllegalArgumentException if <code>pingInterval</code>
   * is less than <code>0</code>.
   *
   * @see CacheServer#setMaximumTimeBetweenPings(int)
   */
  PoolFactory& setPingInterval(std::chrono::milliseconds pingInterval);

  /**
   * The frequency with which client updates the locator list. To disable this
   * set its value to std::chrono::milliseconds::zero().
   *
   * @param updateLocatorListInterval is the amount of time
   * between checking locator list at locator.
   * @return a reference to <code>this</code>
   */
  PoolFactory& setUpdateLocatorListInterval(
      std::chrono::milliseconds updateLocatorListInterval);

  /**
   * The frequency with which the client statistics must be sent to the server.
   * Doing this allows <code>GFMon</code> to monitor clients.
   * <p>A value of <code>std::chrono::milliseconds::zero()</code> disables the
   * sending of client statistics to the server.
   *
   * @param statisticInterval is the amount of time between
   * sends of client statistics to the server.
   *
   * @return a reference to <code>this</code>
   * @throws IllegalArgumentException if <code>statisticInterval</code>
   * is less than <code>std::chrono::milliseconds::zero()</code>.
   */
  PoolFactory& setStatisticInterval(
      std::chrono::milliseconds statisticInterval);

  /**
   * Configures the group which contains all the servers that this pool connects
   * to.
   * @param group is the server group that this pool will connect to.
   * If the value is <code>null</code> or <code>""</code> then the pool connects
   * to all servers.
   * @return a reference to <code>this</code>
   */
  PoolFactory& setServerGroup(std::string group);

  /**
   * Adds a locator, given its host and port, to this factory.
   * The locator must be a server locator and will be used to discover other
   * running
   * bridge servers and locators.
   * @param host is the host name or ip address that the locator is listening
   * on.
   * @param port is the port that the locator is listening on.
   * @return a reference to <code>this</code>
   * @throws IllegalArgumentException if the <code>host</code> is an unknown
   * host
   * according to {@link java.net.InetAddress#getByName} or if the port is
   * outside
   * the valid range of [1..65535] inclusive.
   * @throws IllegalStateException if the locator has already been {@link
   * #addServer added} to this factory.
   */
  PoolFactory& addLocator(const std::string& host, int port);

  /**
   * Adds a server, given its host and port, to this factory.
   * The server must be a bridge server and this client will
   * directly connect to the server without consulting a server locator.
   * @param host is the host name or ip address that the server is listening on.
   * @param port is the port that the server is listening on.
   * @return a reference to <code>this</code>
   * @throws IllegalArgumentException if the <code>host</code> is an unknown
   * host
   * according to {@link java.net.InetAddress#getByName} or if the port is
   * outside
   * the valid range of [1..65535] inclusive.
   * @throws IllegalStateException if the server has already been {@link
   * #addLocator added} to this factory.
   */
  PoolFactory& addServer(const std::string& host, int port);

  /**
   * If set to <code>true</code> then the created pool will have
   * server-to-client
   * subscriptions enabled.
   * If set to <code>false</code> then all <code>Subscription*</code> attributes
   * are ignored at the time of creation.
   * @return a reference to <code>this</code>
   */
  PoolFactory& setSubscriptionEnabled(bool enabled);

  /**
   * Sets the redundancy level for this pools server-to-client subscriptions.
   * If <code>0</code> then no redundant copies are kept on the servers.
   * Otherwise an effort is made to maintain the requested number of
   * copies of the server-to-client subscriptions. At most, one copy per server
   * is
   *  made up to the requested level.
   * @param redundancy is the number of redundant servers for this client's
   * subscriptions.
   * @return a reference to <code>this</code>
   * @throws IllegalArgumentException if <code>redundancyLevel</code>
   * is less than <code>-1</code>.
   */
  PoolFactory& setSubscriptionRedundancy(int redundancy);

  /**
   * Sets the messageTrackingTimeout attribute which is the time-to-live period
   * for subscription events the client has received from the server. It is used
   * to minimize duplicate events. Entries that have not been modified for this
   * amount of time  are expired from the list.
   *
   * @param messageTrackingTimeout is the duration to set the timeout to.
   * @return a reference to <code>this</code>
   *
   * @throws IllegalArgumentException if <code>messageTrackingTimeout</code>
   * is less than or equal to <code>0</code>.

   */
  PoolFactory& setSubscriptionMessageTrackingTimeout(
      std::chrono::milliseconds messageTrackingTimeout);

  /**
   * Sets the is the interval to wait before sending acknowledgements to the
   * bridge server for events received from the server subscriptions.
   *
   * @param ackInterval is the duration to wait before sending  event
   * acknowledgements.
   *
   * @throws IllegalArgumentException if <code>ackInterval</code>
   * is less than or equal to <code>0</code>.
   * @return a reference to <code>this</code>
   */
  PoolFactory& setSubscriptionAckInterval(
      std::chrono::milliseconds ackInterval);

  /**
   * Sets whether Pool is in multi user secure mode.
   * If its in multiuser mode then app needs to get RegionService instance of
   * Cache.
   * Default value is false.
   * @return a reference to <code>this</code>
   */
  PoolFactory& setMultiuserAuthentication(bool multiuserAuthentication);

  /**
   * Resets the configuration of this factory to its defaults.
   * @return a reference to <code>this</code>
   */
  PoolFactory& reset();

  /**
   * Creates a new Pool for connecting a client to a set of Geode Cache
   * Servers.
   * using this factory's settings for attributes.
   *
   * @param name is the name of the pool, used when connecting regions to it
   * @throws IllegalStateException if a pool with <code>name</code> already
   * exists
   * @throws IllegalStateException if a locator or server has not been added.
   * @return the newly created pool.
   */
  std::shared_ptr<Pool> create(std::string name);

  /**
   * By default setPRSingleHopEnabled is true.<br>
   * The client is aware of the locations of partitions on servers hosting
   * partitioned regions.
   * Using this information, the client routes client cache operations
   * directly to the server which is hosting the required partition for the
   * cache operation.
   * If setPRSingleHopEnabled is false the client can do an extra hop on servers
   * to go to the required partition for that cache operation.
   * The setPRSingleHopEnabled setting avoids extra hops only for the following
   * cache operations:<br>
   * 1. {@link Region#put(Object, Object)}<br>
   * 2. {@link Region#get(Object)}<br>
   * 3. {@link Region#destroy(Object)}<br>
   * If true, works best when {@link PoolFactory#setMaxConnections(int)} is set
   * to -1.
   * @param enabled is a boolean indicating whether PR Single Hop optimization
   * should be enabled or not.
   * @return a reference to <code>this</code>
   */
  PoolFactory& setPRSingleHopEnabled(bool enabled);

  ~PoolFactory() = default;

  PoolFactory(const PoolFactory&) = default;

 private:
  explicit PoolFactory(const Cache& cache);
  PoolFactory& addCheck(const std::string& host, int port);
  std::shared_ptr<PoolAttributes> m_attrs;
  bool m_isSubscriptionRedundancy;
  bool m_addedServerOrLocator;
  const Cache& m_cache;

  friend class Cache;
  friend class PoolManager;
  friend class PoolManagerImpl;
  friend class CacheFactory;
  friend class CacheXmlCreation;
};

}  // namespace client
}  // namespace geode
}  // namespace apache

#endif  // GEODE_POOLFACTORY_H_
