/*
 * 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_CACHE_H_
#define GEODE_CACHE_H_

#include <string>

#include <geode/util/LogLevel.hpp>

#include "GeodeCache.hpp"
#include "internal/geode_globals.hpp"

namespace apache {
namespace geode {
namespace client {

class AuthenticatedView;
class AuthInitialize;
class CacheFactory;
class CacheImpl;
class CacheRegionHelper;
class CacheTransactionManager;
class DataInput;
class DataOutput;
class Pool;
class PoolFactory;
class PoolManager;
class Properties;
class QueryService;
class Region;
class RegionFactory;
class TypeRegistry;
enum class RegionShortcut;

/**
 * @class Cache Cache.hpp
 *
 * Caches are obtained from the create method on the {@link CacheFactory#create}
 * class
 * <p>
 * When a cache will no longer be used, it should be {@link #close closed}.
 * Once it {@link Cache::isClosed is closed} any attempt to use it
 * will cause a <code>CacheClosedException</code> to be thrown.
 *
 * <p>A cache can have multiple root regions, each with a different name.
 *
 */
class APACHE_GEODE_EXPORT Cache : public GeodeCache {
 public:
  /**
   * Returns the {@link RegionFactory} to create the region.
   * Before creating the Region, one can set region attributes using this
   * instance.
   *
   * @param regionShortcut
   *        To create the region specific type, @see RegionShortcut
   */
  virtual RegionFactory createRegionFactory(RegionShortcut regionShortcut);

  /**
   * Initializes the cache from an xml file
   *
   * @param cacheXml
   *        Valid cache.xml file
   */
  void initializeDeclarativeCache(const std::string& cacheXml) override;

  /** Returns the name of this cache.
   * @return the string name of this cache
   */
  const std::string& getName() const override;

  /**
   * Indicates if this cache has been closed.
   * After a new cache object is created, this method returns false;
   * After the close is called on this cache object, this method
   * returns true.
   *
   * @return true, if this cache is closed; false, otherwise
   */
  bool isClosed() const override;

  /**
   * Returns the type registry that this cache was
   * {@link CacheFactory::create created} with.
   */
  TypeRegistry& getTypeRegistry() const;

  /**
   * Terminates this object cache and releases all the local resources.
   * After this cache is closed, any further
   * method call on this cache or any region object will throw
   * <code>CacheClosedException</code>, unless otherwise noted.
   * If Cache instance created from Pool(pool is in multiuser mode), then it
   * reset user related security data.
   * @throws CacheClosedException,  if the cache is already closed.
   */
  void close() override;

  /**
   * Terminates this object cache and releases all the local resources.
   * After this cache is closed, any further
   * method call on this cache or any region object will throw
   * <code>CacheClosedException</code>, unless otherwise noted.
   * If Cache instance created from Pool(pool is in multiuser mode), then it
   * reset user related security data.
   * @param keepalive whether to keep a durable client's queue alive
   * @throws CacheClosedException,  if the cache is already closed.
   */
  virtual void close(bool keepalive);

  /** Look up a region with the full path from root.
   *
   * If Pool attached with Region is in multiusersecure mode then don't use
   * return instance of region as no credential are attached with this instance.
   * Get region from RegionService instance of Cache.@see
   * Cache#createAuthenticatedView(std::shared_ptr<Properties>).
   *
   * @param path the region's name, such as <code>AuthRegion</code>.
   * @returns region, or nullptr if no such region exists.
   */
  std::shared_ptr<Region> getRegion(const std::string& path) const override;

  /**
   * Returns a set of root regions in the cache. This set is a snapshot and
   * is not backed by the Cache. The vector passed in is cleared and the
   * regions are added to it.
   */
  std::vector<std::shared_ptr<Region>> rootRegions() const override;

  /**
   * Gets the QueryService from which a new Query can be obtained.
   * @returns A smart pointer to the QueryService.
   */
  std::shared_ptr<QueryService> getQueryService() override;

  /**
   * Gets the QueryService from which a new Query can be obtained.
   * @param poolName
   *        Pass poolname if pool is created from cache.xml or {@link
   * PoolManager}
   * @returns A smart pointer to the QueryService.
   */
  virtual std::shared_ptr<QueryService> getQueryService(
      const std::string& poolName) const;

  /**
   * Send the "client ready" message to the server from a durable client.
   */
  virtual void readyForEvents();

  /**
   * Creates an authenticated cache using the given user security properties.
   * Multiple instances with different user properties can be created with a
   * single client cache.
   *
   * Application must use this instance to do operations, when
   * multiuser-authentication is set to true.
   *
   * @see RegionService
   * @see PoolFactory#setMultiuserAuthentication(boolean)
   * @return the {@link RegionService} instance associated with a user and
   * given properties.
   * @throws UnsupportedOperationException
   *           when invoked with multiuser-authentication as false.
   *
   * @param userSecurityProperties
   *        the security properties of a user.
   *
   * @param poolName
   *        the pool that the users should be authenticated against. Set if
   * there are more than one Pool in Cache.
   */

  virtual AuthenticatedView createAuthenticatedView(
      const std::shared_ptr<Properties>& userSecurityProperties,
      const std::string& poolName);

  /**
   * Get the CacheTransactionManager instance for this Cache.
   * @return The CacheTransactionManager instance.
   * @throws CacheClosedException if the cache is closed.
   */
  virtual std::shared_ptr<CacheTransactionManager> getCacheTransactionManager()
      const;

  /**
   * Returns whether Cache saves unread fields for Pdx types.
   */
  bool getPdxIgnoreUnreadFields() const override;

  /**
   * Returns whether { @link PdxInstance} is preferred for PDX types instead of
   * C++ object.
   */
  bool getPdxReadSerialized() const override;

  /**
   * Returns a factory that can create a {@link PdxInstance}.
   * @param className the fully qualified class name that the PdxInstance will
   * become when it is fully deserialized.
   * @throws IllegalStateException if the className is nullptr or invalid.
   * @return the factory
   */
  PdxInstanceFactory createPdxInstanceFactory(
      const std::string& className) const override;

  /**
   * Returns a factory that can create a {@link PdxInstance}.
   * @param className the fully qualified class name that the PdxInstance will
   * become when it is fully deserialized.
   * @param expectDomainClass Whether or not created PdxType represents a
   * Java domain class.
   * @throws IllegalStateException if the className is nullptr or invalid.
   * @return the factory
   */
  PdxInstanceFactory createPdxInstanceFactory(
      const std::string& className, bool expectDomainClass) const override;

  virtual DataInput createDataInput(const uint8_t* m_buffer, size_t len) const;

  virtual DataOutput createDataOutput() const;

  virtual PoolManager& getPoolManager() const;

  SystemProperties& getSystemProperties() const override;

  /**
   * Changes the current log level to newLogLevel.
   */
  void setLogLevel(LogLevel newLevel);

  /**
   * Returns the current log level.
   * @return the current log level.
   */
  LogLevel getLogLevel();

  Cache() = delete;
  ~Cache() override;

  Cache(const Cache& other) = delete;
  Cache& operator=(const Cache& other) = delete;
  Cache(Cache&& other) noexcept;
  Cache& operator=(Cache&& other) noexcept;

 private:
  Cache(const std::shared_ptr<Properties>& dsProp, bool ignorePdxUnreadFields,
        bool readPdxSerialized,
        const std::shared_ptr<AuthInitialize>& authInitialize);

  std::unique_ptr<CacheImpl> m_cacheImpl;

 protected:
  friend class CacheFactory;
  friend class CacheRegionHelper;
  friend class FunctionService;
  friend class CacheXmlCreation;
  friend class RegionXmlCreation;
};

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

#endif  // GEODE_CACHE_H_
