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


#include "geode_defs.hpp"
#include "IGeodeCache.hpp"
#include "native_shared_ptr.hpp"

#include "begin_native.hpp"
#include <geode/Cache.hpp>
#include "end_native.hpp"

using namespace System;

namespace Apache
{
  namespace Geode
  {
    namespace Client
    {
      namespace Internal {
        ref class PdxTypeRegistry;
      } // namespace Internal

      namespace native = apache::geode::client;

      ref class QueryService;

      ref class RegionFactory;
      
      enum class ExpirationAction;

      enum class RegionShortcut;
            
      ref class CacheTransactionManager2PC;
      
      generic<class TPropKey, class TPropValue>
      ref class Properties;

      ref class PoolFactory;

      ref class PoolManager;

      ref class DataInput;

      ref class DataOutput;

      ref class TypeRegistry;

      /// <summary>
      /// Provides a distributed cache.
      /// </summary>
      /// <remarks>
      /// Caches are obtained from Create methods on the
      /// <see cref="CacheFactory.Create"/> class.
      /// <para>
      /// When a cache will no longer be used, call <see cref="Cache.Close" />.
      /// Once it <see cref="Cache.IsClosed" /> any attempt to use it
      /// will cause a <c>CacheClosedException</c> to be thrown.
      /// </para><para>
      /// A cache can have multiple root regions, each with a different name.
      /// </para>
      /// </remarks>
      public ref class Cache sealed
        : public IGeodeCache
      {
      public:

        /// <summary>
        /// Initializes the cache from an XML file.
        /// </summary>
        /// <param name="cacheXml">pathname of a <c>cache.xml</c> file</param>
        virtual void InitializeDeclarativeCache(String^ cacheXml);

        /// <summary>
        /// Returns the name of this cache.
        /// </summary>
        /// <remarks>
        /// This method does not throw
        /// <c>CacheClosedException</c> if the cache is closed.
        /// </remarks>
        /// <returns>the string name of this cache</returns>
        virtual property String^ Name
        {
          String^ get();
        }

        /// <summary>
        /// True if this cache has been closed.
        /// </summary>
        /// <remarks>
        /// After a new cache object is created, this method returns false.
        /// After <see cref="Close" /> is called on this cache object, this method
        /// returns true.
        /// </remarks>
        /// <returns>true if this cache is closed, otherwise false</returns>
        virtual property bool IsClosed
        {
          bool get();
        }

        virtual property SystemProperties^ SystemProperties
        {
          Apache::Geode::Client::SystemProperties^ get();
        }

        /// <summary>
        /// Returns the cache transaction manager of
        /// <see cref="CacheFactory.Create" /> this cache.
        /// </summary>
        virtual property Apache::Geode::Client::CacheTransactionManager^ CacheTransactionManager
        {
          Apache::Geode::Client::CacheTransactionManager^ get();
        }

        /// <summary>
        /// Terminates this object cache and releases all the local resources.
        /// </summary>
        /// <remarks>
        /// After this cache is closed, any further
        /// method call on this cache or any region object will throw
        /// <c>CacheClosedException</c>, unless otherwise noted.
        /// </remarks>
        /// <exception cref="CacheClosedException">
        /// if the cache is already closed.
        /// </exception>
        virtual void Close();

        /// <summary>
        /// Terminates this object cache and releases all the local resources.
        /// </summary>
        /// <remarks>
        /// After this cache is closed, any further
        /// method call on this cache or any region object will throw
        /// <c>CacheClosedException</c>, unless otherwise noted.
        /// </remarks>
        /// <param name="keepalive">whether to keep a durable client's queue alive</param>
        /// <exception cref="CacheClosedException">
        /// if the cache is already closed.
        /// </exception>
        virtual void Close(bool keepalive);

        /// <summary>
        /// Send the client-ready message to the server for a durable client.        
        /// </summary>
        /// <remarks>
        /// This method should only be called for durable clients and
        /// with a cache server version 5.5 onwards.
        /// </remarks>
        /// <exception cref="IllegalStateException">
        /// if there was a problem sending the message to the server.
        /// </exception>
        virtual void ReadyForEvents();

        /// <summary>
        /// Returns an existing region given the full path from root, or null 
        /// if no such region exists.
        /// </summary>
        /// <remarks>
        /// 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 cref="Cache.CreateAuthenticatedView(std::shared_ptr<PropertiesPtr>)" />.
        /// </remarks>
        /// <param name="path">the pathname of the region</param>
        /// <returns>the region</returns>
        generic<class TKey, class TValue>
        virtual IRegion<TKey, TValue>^ GetRegion(String^ path);

        /// <summary>
        /// Returns an array of root regions in the cache. This set is a
        /// snapshot and is not backed by the cache.
        /// </summary>
        /// <remarks>
        /// It is not supported when Cache is created from Pool.
        /// </remarks>
        /// <returns>array of regions</returns>
        generic<class TKey, class TValue>
        virtual array<IRegion<TKey, TValue>^>^ RootRegions();

        /// <summary>
        /// Get a query service object to be able to query the cache.
        /// Supported only when cache is created from Pool(pool is in multiuserSecure mode)
        /// </summary>
        /// <remarks>
        /// Currently only works against the java server in native mode, and
        /// at least some endpoints must have been defined in some regions
        /// before actually firing a query.
        /// </remarks>
        virtual Client::QueryService^ GetQueryService();

        /// <summary>
        /// Get a query service object to be able to query the cache.
        /// Use only when Cache has more than one Pool.
        /// </summary>
        /// <remarks>
        /// Currently only works against the java server in native mode, and
        /// at least some endpoints must have been defined in some regions
        /// before actually firing a query.
        /// </remarks>
        virtual Client::QueryService^ GetQueryService(String^ poolName);

        /// <summary>
        /// Returns the instance of <see cref="RegionFactory" /> to create the region
        /// </summary>
        /// <remarks>
        /// Pass the <see cref="RegionShortcut" /> to set the deafult region attributes
        /// </remarks>
        /// <param name="regionShortcut">the regionShortcut to set the default region attributes</param>
        /// <returns>Instance of RegionFactory</returns>
        RegionFactory^ CreateRegionFactory(RegionShortcut regionShortcut);

        /// <summary>
        /// Returns the instance of <see cref="IRegionService" /> to do the operation on Cache with different Credential.
        /// </summary>
        /// <remarks>
        /// Deafault pool should be in multiuser mode <see cref="CacheFactory.SetMultiuserAuthentication" />
        /// </remarks>
        /// <param name="credentials">the user Credentials.</param>
        /// <returns>Instance of IRegionService</returns>
        IRegionService^ CreateAuthenticatedView(Properties<String^, Object^>^ credentials);

        /// <summary>
        /// Returns the instance of <see cref="IRegionService" /> to do the operation on Cache with different Credential.
        /// </summary>
        /// <remarks>
        /// Deafault pool should be in multiuser mode <see cref="CacheFactory.SetMultiuserAuthentication" />
        /// </remarks>
        /// <param name="credentials">the user Credentials.</param>
        /// <param name="poolName">Pool, which is in multiuser mode.</param>
        /// <returns>Instance of IRegionService</returns>
        IRegionService^ CreateAuthenticatedView(Properties<String^, Object^>^ credentials, String^ poolName);

        ///<summary>
        /// Returns whether Cache saves unread fields for Pdx types.
        ///</summary>
        virtual bool GetPdxIgnoreUnreadFields();

        ///<summary>
        /// Returns whether { @link PdxInstance} is preferred for PDX types instead of .NET object.
        ///</summary>
        virtual bool GetPdxReadSerialized();

        /// <summary>
        /// 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.
        /// @return the factory
        /// </summary>
        virtual IPdxInstanceFactory^ CreatePdxInstanceFactory(String^ className);

        virtual DataInput^ CreateDataInput(array<Byte>^ buffer, System::Int32 len);
        virtual DataInput^ CreateDataInput(array<Byte>^ buffer);
        
        virtual DataOutput^ Cache::CreateDataOutput();

        virtual PoolFactory^ GetPoolFactory();

        virtual PoolManager^ GetPoolManager();

        property Apache::Geode::Client::TypeRegistry^ TypeRegistry
        {
          Apache::Geode::Client::TypeRegistry^ get() { return m_typeRegistry; }
        }

      internal:

        /// <summary>
        /// Internal factory function to wrap a native object pointer inside
        /// this managed class with null pointer check.
        /// </summary>
        /// <param name="nativeptr">The native object pointer</param>
        /// <returns>
        /// The managed wrapper object; null if the native pointer is null.
        /// </returns>
        inline static Cache^ Create(std::shared_ptr<native::Cache> nativeptr)
        {
          return __nullptr == nativeptr ? nullptr :
            gcnew Cache( nativeptr );
        }

        std::shared_ptr<native::Cache> GetNative()
        {
          return m_nativeptr->get_shared_ptr();
        }

        Apache::Geode::Client::Internal::PdxTypeRegistry^ GetPdxTypeRegistry()
        {
          return m_pdxTypeRegistry;
        }
		        
		Apache::Geode::Client::TypeRegistry^ GetTypeRegistry()
        {
          return m_typeRegistry;
        }
      private:

        /// <summary>
        /// Private constructor to wrap a native object pointer
        /// </summary>
        /// <param name="nativeptr">The native object pointer</param>
        Cache(std::shared_ptr<native::Cache> nativeptr);

        native_shared_ptr<native::Cache>^ m_nativeptr;

        Apache::Geode::Client::Internal::PdxTypeRegistry^ m_pdxTypeRegistry;
        Apache::Geode::Client::TypeRegistry^ m_typeRegistry;
      };
    }  // namespace Client
  }  // namespace Geode
}  // namespace Apache

