/*
 * 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_POOL_H_
#define GEODE_POOL_H_

#include <chrono>
#include <iosfwd>
#include <memory>

#include "Cache.hpp"
#include "CacheFactory.hpp"
#include "CacheableBuiltins.hpp"
#include "internal/geode_base.hpp"
#include "internal/geode_globals.hpp"
#include "internal/chrono/duration.hpp"

/**
 * @file
 */

namespace apache {
namespace geode {
namespace client {

class AuthenticatedView;
class Cache;
class CacheFactory;
class PoolAttributes;
class CacheImpl;
class Properties;
class QueryService;

/**
 * A pool of connections to connect from a client to a set of Geode Cache
 * Servers.
 * <p>Instances of this interface are created using
 * {@link PoolFactory#create}.
 * <p>Existing instances can be found using {@link PoolFactory#find}
 * and {@link PoolFactory#getAll}.
 * <p>The pool name must be configured
 * on the client regions that will use this pool by calling
 * {@link AttributeFactory#setPoolName}.
 *
 *
 */
class APACHE_GEODE_EXPORT Pool : public std::enable_shared_from_this<Pool> {
 public:
  /**
   * Gets the name of the connection pool
   *
   * @return the name of the pool
   * @see PoolFactory#create
   */
  virtual const std::string& getName() const = 0;

  /**
   * Returns the connection timeout of this pool.
   * @see PoolFactory#setFreeConnectionTimeout
   */
  std::chrono::milliseconds getFreeConnectionTimeout() const;

  /**
   * Returns the load conditioning interval of this pool.
   * @see PoolFactory#setLoadConditioningInterval
   */
  std::chrono::milliseconds getLoadConditioningInterval() const;

  /**
   * Returns the socket buffer size of this pool.
   * @see PoolFactory#setSocketBufferSize
   */
  int getSocketBufferSize() const;

  /**
   * Returns the read timeout of this pool.
   * @see PoolFactory#setReadTimeout
   */
  std::chrono::milliseconds getReadTimeout() const;

  /**
   * Gets the minimum connections for this pool.
   * @see PoolFactory#setMinConnections(int)
   */
  int getMinConnections() const;

  /**
   * Gets the maximum connections for this pool.
   * @see PoolFactory#setMaxConnections(int)
   */
  int getMaxConnections() const;

  /**
   * Gets the idle connection timeout for this pool.
   * @see PoolFactory#setIdleTimeout(long)
   */
  std::chrono::milliseconds getIdleTimeout() const;

  /**
   * Gets the ping interval for this pool.
   * @see PoolFactory#setPingInterval(long)
   */
  std::chrono::milliseconds getPingInterval() const;

  /**
   * Gets the update locator list interval for this pool.
   * @see PoolFactory#setUpdateLocatorListInterval(long)
   */
  std::chrono::milliseconds getUpdateLocatorListInterval() const;

  /**
   * Gets the statistic interval for this pool.
   * @see PoolFactory#setStatisticInterval(int)
   */
  std::chrono::milliseconds getStatisticInterval() const;

  /**
   * Gets the retry attempts for this pool.
   * @see PoolFactory#setRetryAttempts(int)
   */
  int getRetryAttempts() const;

  /**
   * Returns the true if a server-to-client subscriptions are enabled on this
   * pool.
   * @see PoolFactory#setSubscriptionEnabled
   */
  bool getSubscriptionEnabled() const;

  /**
   * Returns the subscription redundancy level of this pool.
   * @see PoolFactory#setSubscriptionRedundancy
   */
  int getSubscriptionRedundancy() const;

  /**
   * Returns the subscription message tracking timeout of this pool.
   * @see PoolFactory#setSubscriptionMessageTrackingTimeout
   */
  std::chrono::milliseconds getSubscriptionMessageTrackingTimeout() const;

  /**
   * Returns the subscription ack interval of this pool.
   * @see PoolFactory#setSubscriptionAckInterval(int)
   */
  std::chrono::milliseconds getSubscriptionAckInterval() const;

  /**
   * Returns the server group of this pool.
   * @see PoolFactory#setServerGroup
   */
  const std::string& getServerGroup() const;

  /**
   * Returns <code>true</code> if thread local connections are enabled on this
   * pool.
   * @see PoolFactory#setThreadLocalConnections
   */
  bool getThreadLocalConnections() const;

  /**
   * Returns <code>true</code> if multiuser authentication is enabled on this
   * pool.
   * @see PoolFactory#setMultiuserAuthentication
   */
  bool getMultiuserAuthentication() const;

  /**
   * Returns true if single-hop optimisation is enabled on this pool.
   * @see PoolFactory#setPRSingleHopEnabled
   */
  bool getPRSingleHopEnabled() const;

  /**
   * If this pool was configured to use <code>threadlocalconnections</code>,
   * then this method will release the connection cached for the calling thread.
   * The connection will then be available for use by other threads.
   *
   * If this pool is not using <code>threadlocalconnections</code>, this method
   * will have no effect.
   */
  virtual void releaseThreadLocalConnection() = 0;

  /**
   * Returns an unmodifiable list locators that
   * this pool is using. Each locator was either
   * {@link PoolFactory#addLocator added explicitly}
   * when the pool was created or was discovered using the explicit locators.
   * <p> If a pool has no locators, then it cannot discover servers or locators
   * at runtime.
   */
  virtual const std::shared_ptr<CacheableStringArray> getLocators() const = 0;

  /**
   * Returns an unmodifiable list of
   * servers this pool is using. These servers where either
   * {@link PoolFactory#addServer added explicitly}
   * when the pool was created or were discovered using this pools {@link
   * #getLocators locators}.
   */
  virtual const std::shared_ptr<CacheableStringArray> getServers() = 0;

  /**
   * Destroys this pool closing any connections it produced.
   * @param keepAlive defines
   *                whether the server should keep the durable client's
   *                subscriptions alive for the timeout period.
   * @throws IllegalStateException
   *                 if the pool is still in use.
   */
  virtual void destroy(bool keepAlive = false) = 0;

  /**
   * Indicates whether this Pool has been
   * destroyed.
   *
   * @return true if the pool has been destroyed.
   */
  virtual bool isDestroyed() const = 0;

  /**
   * Returns the QueryService for this Pool.
   * The query operations performed using this QueryService will be executed
   * on the servers that are associated with this pool.
   * To perform Query operation on the local cache obtain the QueryService
   * instance from the Cache.
   * @throws unSupported Exception when Pool is in multi user mode.
   *
   * @see Cache#getQueryService
   * @return the QueryService
   */
  virtual std::shared_ptr<QueryService> getQueryService() = 0;

  virtual ~Pool();

  /**
   * Returns the approximate number of pending subscription events maintained at
   * server for this durable client pool at the time it (re)connected to the
   * server. Server would start dispatching these events to this durable client
   * pool when it receives {@link Cache#readyForEvents()} from it.
   * <p>
   * Durable clients can call this method on reconnect to assess the amount of
   * 'stale' data i.e. events accumulated at server while this client was away
   * and, importantly, before calling {@link Cache#readyForEvents()}.
   * <p>
   * Any number of invocations of this method during a single session will
   * return the same value.
   * <p>
   * It may return a zero value if there are no events pending at server for
   * this client pool. A negative value returned tells us that no queue was
   * available at server for this client pool.
   * <p>
   * A value -1 indicates that this client pool reconnected to server after its
   * 'durable-client-timeout' period elapsed and hence its subscription queue at
   * server was removed, possibly causing data loss.
   * <p>
   * A value -2 indicates that this client pool connected to server for the
   * first time.
   *
   * @return int The number of subscription events maintained at server for this
   *         durable client pool at the time this pool (re)connected. A negative
   *         value indicates no queue was found for this client pool.
   * @throws IllegalStateException
   *           If called by a non-durable client or if invoked any time after
   *           invocation of {@link Cache#readyForEvents()}.
   * @since 8.1
   */
  int getPendingEventCount() const;

 protected:
  explicit Pool(std::shared_ptr<PoolAttributes> attr);
  std::shared_ptr<PoolAttributes> m_attrs;

 private:
  /**
   * Returns the logical instance of cache from pool.
   * Each operation on this cache will use this "credentials"
   *
   * @throws IllegalStateException if cache has not been created or it has been
   * closed.
   *        Or if Pool is not in multiusersecure mode.
   * @returns Logical instance of cache to do operations on behalf of one
   * particular user.
   */
  virtual AuthenticatedView createAuthenticatedView(
      std::shared_ptr<Properties> credentials, CacheImpl* cacheImpl);

  Pool(const Pool&);

  friend class PoolFactory;
  friend class CacheFactory;
  friend class CacheImpl;
};

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

#endif  // GEODE_POOL_H_
