/*
 * 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 "IDataSerializablePrimitive.hpp"

using namespace System;

namespace Apache
{
  namespace Geode
  {
    namespace Client
    {

      /// <summary>
      /// An mutable generic <see cref="System.Object" /> wrapper that can
      /// serve as a distributable value for caching.
      /// </summary>
      /// <remarks>
      /// <para>
      /// This class can serialize any class which has either the
      /// [Serializable] attribute set or implements
      /// <see cref="System.Runtime.Serialization.ISerializable" /> interface.
      /// However, for better efficiency the latter should be avoided and the
      /// user should implement <see cref="../../ISerializable" /> instead.
      /// </para><para>
      /// The user must keep in mind that the rules that apply to runtime
      /// serialization would be the rules that apply to this class. For
      /// the serialization will be carried out by serializing all the
      /// members (public/private/protected) of the class. Each of the
      /// contained classes should also have either the [Serializable]
      /// attribute set or implement <c>ISerializable</c> interface.
      /// </para>
      /// </remarks>
      public ref class CacheableObject
        : public IDataSerializablePrimitive
      {
      public:
        /// <summary>
        /// Static function to create a new instance from the given object.
        /// </summary>
        /// <remarks>
        /// If the given object is null then this method returns null.
        /// </remarks>
        inline static CacheableObject^ Create(Object^ value)
        {
          return (value != nullptr ? gcnew CacheableObject(value) :
                  nullptr);
        }

        virtual void ToData(DataOutput^ output);

        virtual void FromData(DataInput^ input);

        virtual property System::UInt64 ObjectSize
        {
          virtual System::UInt64 get();
        }

        property int8_t DsCode
        {
          virtual int8_t get()
          {
            return static_cast<int8_t>(apache::geode::client::internal::InternalId::CacheableManagedObject);
          }
        }

        /// <summary>
        /// Gets the object value.
        /// </summary>
        /// <remarks>
        /// The user can modify the object and the changes shall be reflected
        /// immediately in the local cache. For this change to be propagate to
        /// other members of the distributed system, the object needs to be
        /// put into the cache.
        /// </remarks>
        property Object^ Value
        {
          inline Object^ get()
          {
            return m_obj;
          }
        }

        virtual String^ ToString() override
        {
          return (m_obj == nullptr ? nullptr : m_obj->ToString());
        }

        /// <summary>
        /// Factory function to register this class.
        /// </summary>
        static ISerializable^ CreateDeserializable()
        {
          return gcnew CacheableObject(nullptr);
        }

      internal:
        /// <summary>
        /// Allocates a new instance from the given object.
        /// </summary>
        inline CacheableObject(Object^ value)
          : m_obj(value), m_objectSize(0) { }



      private:
        Object^ m_obj;
        System::UInt64 m_objectSize;
      };
    }  // namespace Client
  }  // namespace Geode
}  // namespace Apache

