/*=========================================================================
 * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
 * This product is protected by U.S. and international copyright
 * and intellectual property laws. Pivotal products are covered by
 * one or more patents listed at http://www.pivotal.io/patents.
 *=========================================================================
 */
#include "ReflectionBasedAutoSerializer.hpp"
#include "PdxIdentityFieldAttribute.hpp"
#include "SerializableMN.hpp"
#pragma warning(disable:4091)
#include <msclr/lock.h>
#include "ExceptionTypesMN.hpp"
#include "impl/DotNetTypes.hpp"
namespace GemStone
{
  namespace GemFire
  {
    namespace Cache
    {
      namespace Generic
      {
         ref class FieldWrapper
        {
          private:
             //static readonly Module Module = typeof(Program).Module;
            static array<Type^>^ oneObj = gcnew array<Type^>(1) { Type::GetType("System.Object") };
            static array<Type^>^ twoObj = gcnew array<Type^>(2) { Type::GetType("System.Object"), Type::GetType("System.Object") };
            delegate void MySetter(Object^ t1, Object^ t2);
            delegate Object^ MyGetter(Object^ t1);

            static Type^ setterDelegateType = Type::GetType("GemStone.GemFire.Cache.Generic.FieldWrapper+MySetter");
            static Type^ getterDelegateType = Type::GetType("GemStone.GemFire.Cache.Generic.FieldWrapper+MyGetter");

            FieldInfo^ m_fi;
            String^    m_fieldName;
            bool       m_isIdentityField;
            FieldType  m_fieldType;
            int        m_pdxType;

            MyGetter^ m_getter;
            MySetter^ m_setter;

            static MySetter^ createFieldSetter(FieldInfo^ fieldInfo)
            {
              DynamicMethod^ dynam = gcnew DynamicMethod("", Internal::DotNetTypes::VoidType , twoObj, fieldInfo->DeclaringType, true);
              ILGenerator^ il = dynam->GetILGenerator();

              if (!fieldInfo->IsStatic)
                pushInstance(il, fieldInfo->DeclaringType);

              il->Emit(OpCodes::Ldarg_1);
              unboxIfNeeded(il, fieldInfo->FieldType);
              il->Emit(OpCodes::Stfld, fieldInfo);
              il->Emit(OpCodes::Ret);

              return (MySetter^)dynam->CreateDelegate( setterDelegateType );
            }

            static MyGetter^ createFieldGetter(FieldInfo^ fieldInfo)
            {
              DynamicMethod^ dynam = gcnew DynamicMethod( "", Internal::DotNetTypes::ObjectType, oneObj, fieldInfo->DeclaringType, true);
              ILGenerator^ il = dynam->GetILGenerator();

              if (!fieldInfo->IsStatic)
                pushInstance(il, fieldInfo->DeclaringType);

              il->Emit(OpCodes::Ldfld, fieldInfo);
              boxIfNeeded(il, fieldInfo->FieldType);
              il->Emit(OpCodes::Ret);

              return (MyGetter^)dynam->CreateDelegate(getterDelegateType);
            }

            static void boxIfNeeded(ILGenerator^ il, Type^ type)
            {
              if (type->IsValueType)
                il->Emit(OpCodes::Box, type);
            }

            static void pushInstance( ILGenerator^ il, Type^ type)
            {
              il->Emit(OpCodes::Ldarg_0);
              if (type->IsValueType)
                il->Emit(OpCodes::Unbox, type);
            }

            static void unboxIfNeeded( ILGenerator^ il, Type^ type)
            {
              if (type->IsValueType)
                il->Emit(OpCodes::Unbox_Any, type);
            }
          public:
            FieldWrapper(FieldInfo^ fi, String^ fieldName, bool isIdentityField, FieldType  fieldtype)
            {
              m_fi = fi;
              m_fieldName = fieldName;
              m_isIdentityField = isIdentityField;
              m_fieldType = fieldtype;

              m_setter = createFieldSetter(fi);
              m_getter = createFieldGetter(fi);
            }

            property bool isIdentityField
            {
              bool get(){return m_isIdentityField;}
            }

            property Type^ FType
            {
               Type^ get() {return m_fi->FieldType;}
            }

            property String^ FieldName
            {
             String^ get(){return m_fieldName;}
            }

            property FieldInfo^ FI
            {
              FieldInfo^  get(){return m_fi;}
            }
            
            void SetFieldValue(Object^ parent, Object^ val)
            {
              m_setter(parent, val);
            }

            Object^ GetFieldValue(Object^ parent)
            {
              return m_getter(parent);
            }

            void SerializeField(IPdxWriter^ w, Object^ value)
            {
              switch(m_fieldType)
              {
                case FieldType::BOOLEAN:
                  w->WriteBoolean(m_fieldName, (bool)value);
                break;
			          case FieldType::BYTE:
                  w->WriteByte(m_fieldName, (SByte)value);
                break;
			          case FieldType::CHAR:
                  w->WriteChar(m_fieldName, (Char)value);
                break;
			          case FieldType::SHORT:
                  w->WriteShort(m_fieldName, (short)value);
                break;
			          case FieldType::INT:
                  w->WriteInt(m_fieldName, (int)value);
                break;
			          case FieldType::LONG:
                  w->WriteLong(m_fieldName, (Int64)value);
                break;
			          case FieldType::FLOAT:
                  w->WriteFloat(m_fieldName, (float)value);
                break;
			          case FieldType::DOUBLE:
                  w->WriteDouble(m_fieldName, (double)value);
                break;
			          case FieldType::DATE:
                  w->WriteDate(m_fieldName, (DateTime)value);
                break;
			          case FieldType::STRING:
                  w->WriteString(m_fieldName, (String^)value);
                break;
			          case FieldType::OBJECT:
                  w->WriteObject(m_fieldName, value);
                break;
			          case FieldType::BOOLEAN_ARRAY:
                  w->WriteBooleanArray(m_fieldName, (array<bool>^)value);
                break;
			          case FieldType::CHAR_ARRAY:
                  w->WriteCharArray(m_fieldName, (array<Char>^)value);
                break;
			          case FieldType::BYTE_ARRAY:
                  w->WriteByteArray(m_fieldName, (array<Byte>^)value);
                break;
			          case FieldType::SHORT_ARRAY:
                  w->WriteShortArray(m_fieldName, (array<Int16>^)value);
                break;
			          case FieldType::INT_ARRAY:
                  w->WriteIntArray(m_fieldName, (array<Int32>^)value);
                break;
			          case FieldType::LONG_ARRAY:
                  w->WriteLongArray(m_fieldName, (array<int64>^)value);
                break;
			          case FieldType::FLOAT_ARRAY:
                  w->WriteFloatArray(m_fieldName, (array<float>^)value);
                break;
			          case FieldType::DOUBLE_ARRAY:
                  w->WriteDoubleArray(m_fieldName, (array<double>^)value);
                break;
			          case FieldType::STRING_ARRAY:
                  w->WriteStringArray(m_fieldName, (array<String^>^)value);
                break;
			          case FieldType::OBJECT_ARRAY:
                  w->WriteObjectArray(m_fieldName, safe_cast<System::Collections::Generic::List<Object^>^>(value));
                break;
			          case FieldType::ARRAY_OF_BYTE_ARRAYS:
                  w->WriteArrayOfByteArrays(m_fieldName, (array<array<Byte>^>^)value);
                break;
			          default:
                  throw gcnew IllegalStateException("Not found FieldType: " + m_fieldType.ToString());
              }
            }

            Object^ DeserializeField(IPdxReader^ r)
            {
             switch(m_fieldType)
              {
                case FieldType::BOOLEAN:
                  return r->ReadBoolean(m_fieldName);
                break;
			          case FieldType::BYTE:
                  return r->ReadByte(m_fieldName);
                break;
			          case FieldType::CHAR:
                  return r->ReadChar(m_fieldName);
                break;
			          case FieldType::SHORT:
                  return r->ReadShort(m_fieldName);
                break;
			          case FieldType::INT:
                  return r->ReadInt(m_fieldName);
                break;
			          case FieldType::LONG:
                  return r->ReadLong(m_fieldName);
                break;
			          case FieldType::FLOAT:
                  return r->ReadFloat(m_fieldName);
                break;
			          case FieldType::DOUBLE:
                  return r->ReadDouble(m_fieldName);
                break;
			          case FieldType::DATE:
                  return r->ReadDate(m_fieldName);
                break;
			          case FieldType::STRING:
                  return r->ReadString(m_fieldName);
                break;
			          case FieldType::OBJECT:
                  return r->ReadObject(m_fieldName);
                break;
			          case FieldType::BOOLEAN_ARRAY:
                  return r->ReadBooleanArray(m_fieldName);
                break;
			          case FieldType::CHAR_ARRAY:
                  return r->ReadCharArray(m_fieldName);
                break;
			          case FieldType::BYTE_ARRAY:
                  return r->ReadByteArray(m_fieldName);
                break;
			          case FieldType::SHORT_ARRAY:
                  return r->ReadShortArray(m_fieldName);
                break;
			          case FieldType::INT_ARRAY:
                  return r->ReadIntArray(m_fieldName);
                break;
			          case FieldType::LONG_ARRAY:
                  return r->ReadLongArray(m_fieldName);
                break;
			          case FieldType::FLOAT_ARRAY:
                  return r->ReadFloatArray(m_fieldName);
                break;
			          case FieldType::DOUBLE_ARRAY:
                  return r->ReadDoubleArray(m_fieldName);
                break;
			          case FieldType::STRING_ARRAY:
                  return r->ReadStringArray(m_fieldName);
                break;
			          case FieldType::OBJECT_ARRAY:
                  return r->ReadObjectArray(m_fieldName);
                break;
			          case FieldType::ARRAY_OF_BYTE_ARRAYS:
                  return r->ReadArrayOfByteArrays(m_fieldName);
                break;
			          default:
                  throw gcnew IllegalStateException("Not found FieldType: " + m_fieldType.ToString());
              }
              return nullptr;
            }



        };

        ReflectionBasedAutoSerializer::ReflectionBasedAutoSerializer()
        {
          PdxIdentityFieldAttribute^ pif = gcnew PdxIdentityFieldAttribute();
          PdxIdentityFieldAttributeType = pif->GetType();
          classNameVsFieldInfoWrapper = gcnew Dictionary<String^, List<FieldWrapper^>^>();
        }

		    bool ReflectionBasedAutoSerializer::ToData( Object^ o,IPdxWriter^ writer )
        {
          serializeFields(o, writer);
          return true;
        }

        Object^ ReflectionBasedAutoSerializer::FromData(String^ o, IPdxReader^ reader )
        {
          return deserializeFields(o, reader);
        }

        void ReflectionBasedAutoSerializer::serializeFields(Object^ o,IPdxWriter^ writer )
        {
          Type^ ty = o->GetType();
         // Log::Debug("ReflectionBasedAutoSerializer::serializeFields classname {0}: objectType {1}", o->GetType()->FullName,o->GetType());
          for each(FieldWrapper^ fi in GetFields(o->GetType()))
          {
           // Log::Debug("ReflectionBasedAutoSerializer::serializeFields fieldName: {0}, fieldType: {1}", fi->FieldName, fi->FType);
           // writer->WriteField(fi->Name, fi->GetValue(o), fi->FieldType);           
           // SerializeField(o, fi, writer);
            //Object^ originalValue = fi->FI->GetValue(o);
            Object^ originalValue = fi->GetFieldValue(o);
            //hook which can overide by app
            originalValue = WriteTransform(fi->FI, fi->FType, originalValue);

            fi->SerializeField(writer, originalValue);

            if(fi->isIdentityField)
            {
             // Log::Debug("ReflectionBasedAutoSerializer::serializeFields fieldName: {0} is identity field.", fi->FieldName);
              writer->MarkIdentityField(fi->FieldName);
            }
          }

        //  serializeBaseClassFields(o, writer, ty->BaseType);
        }

		  
        /*void ReflectionBasedAutoSerializer::SerializeField(Object^ o, FieldInfo^ fi, IPdxWriter^ writer)
        {
          writer->WriteField(fi->Name, fi->GetValue(o), fi->FieldType);
        }

        Object^ ReflectionBasedAutoSerializer::DeserializeField(Object^ o, FieldInfo^ fi, IPdxReader^ reader)
        {
           return reader->ReadField(fi->Name,  fi->FieldType);  
        }*/

        Object^ ReflectionBasedAutoSerializer::deserializeFields(String^ className, IPdxReader^ reader)
        {
          Object^ o = CreateObject(className);
          //Log::Debug("ReflectionBasedAutoSerializer::deserializeFields classname {0}: objectType {1}", className,o->GetType());
          for each(FieldWrapper^ fi in GetFields(o->GetType()))
          {
            //Log::Debug("1ReflectionBasedAutoSerializer::deserializeFields fieldName: {0}, fieldType: {1}", fi->FieldName, fi->FType);
            Object^ serializeValue = fi->DeserializeField(reader);
            serializeValue = ReadTransform( fi->FI, fi->FType, serializeValue);
            //fi->FI->SetValue(o, serializeValue);            
            fi->SetFieldValue(o, serializeValue);
          }

          return o;
          //deserializeBaseClassFields(o, reader, ty->BaseType);
        }
        
        Object^ ReflectionBasedAutoSerializer::CreateObject(String^ className)
        {
          return Serializable::CreateObject(className);
        }

        bool ReflectionBasedAutoSerializer::IsPdxIdentityField(FieldInfo^ fi)
        {
          array<Object^>^ cAttr=  fi->GetCustomAttributes(PdxIdentityFieldAttributeType, true);
          if(cAttr != nullptr && cAttr->Length > 0)
          {
            PdxIdentityFieldAttribute^ pifa = (PdxIdentityFieldAttribute^)(cAttr[0]);
            return true;
          }
          return false;
        }

        List<FieldWrapper^>^ ReflectionBasedAutoSerializer::GetFields(Type^ domaimType)
        {
          List<FieldWrapper^>^ retVal = nullptr;

          String^ className = domaimType->FullName;
          System::Collections::Generic::Dictionary<String^, List<FieldWrapper^>^>^ tmp = classNameVsFieldInfoWrapper;
          tmp->TryGetValue(className, retVal);
          if(retVal != nullptr)
            return retVal;
          msclr::lock lockInstance(classNameVsFieldInfoWrapper);
          {
            tmp = classNameVsFieldInfoWrapper;
            tmp->TryGetValue(className, retVal);
            if(retVal != nullptr)
              return retVal;
             
            List<FieldWrapper^>^ collectFields = gcnew List<FieldWrapper^>();
             while(domaimType != nullptr)
             {
                for each(FieldInfo^ fi in domaimType->GetFields(BindingFlags::Public| BindingFlags::NonPublic | BindingFlags::Instance
                  |BindingFlags::DeclaredOnly
                  ))
                {
                  if(!fi->IsNotSerialized && !fi->IsStatic && !fi->IsLiteral && !fi->IsInitOnly)
                  {
                    //to ignore the fild
                    if(IsFieldIncluded(fi, domaimType))
                    {                      
                      //This are all hooks which app can implement

                      String^ fieldName = GetFieldName(fi, domaimType);
                      bool isIdentityField = IsIdentityField(fi, domaimType);
                      FieldType ft = GetFieldType(fi, domaimType);
  
                      FieldWrapper^ fw = gcnew FieldWrapper(fi, fieldName, isIdentityField, ft);

                      collectFields->Add(fw);
                    }
                  }
                }
                domaimType = domaimType->BaseType;
             }
             tmp = gcnew System::Collections::Generic::Dictionary<String^, List<FieldWrapper^>^>(classNameVsFieldInfoWrapper); 
             tmp->Add(className, collectFields);
             classNameVsFieldInfoWrapper = tmp;

             return collectFields;
          }
        }

        
        String^ ReflectionBasedAutoSerializer::GetFieldName(FieldInfo^ fi, Type^ type)
        {
          return fi->Name;
        }

        bool ReflectionBasedAutoSerializer::IsIdentityField(FieldInfo^ fi, Type^ type)
        {
          return IsPdxIdentityField(fi);
        }

        FieldType ReflectionBasedAutoSerializer::GetFieldType(FieldInfo^ fi, Type^ type)
        {
          return getPdxFieldType(fi->FieldType);
        }

        bool ReflectionBasedAutoSerializer::IsFieldIncluded(FieldInfo^ fi, Type^ type)
        {
          return true;
        }

        Object^ ReflectionBasedAutoSerializer::WriteTransform(FieldInfo^ fi, Type^ type, Object^ originalValue)
        {
          return originalValue;
        }

        Object^ ReflectionBasedAutoSerializer::ReadTransform(FieldInfo^ fi, Type^ type, Object^ serializeValue)
        {
          return serializeValue;
        }

        FieldType ReflectionBasedAutoSerializer::getPdxFieldType( Type^ type)
        {
          if(type->Equals(Internal::DotNetTypes::IntType))
          {
            return FieldType::INT;
          }
          else if(type->Equals(Internal::DotNetTypes::StringType))
          {
            return FieldType::STRING;
          }
          else if(type->Equals(Internal::DotNetTypes::BooleanType))
          {
            return FieldType::BOOLEAN;
          }
          else if(type->Equals(Internal::DotNetTypes::FloatType))
          {
            return FieldType::FLOAT;
          }
          else if(type->Equals(Internal::DotNetTypes::DoubleType))
          {
            return FieldType::DOUBLE;
          }
          else if(type->Equals(Internal::DotNetTypes::CharType))
          {
            return FieldType::CHAR;
          }
          else if(type->Equals(Internal::DotNetTypes::SByteType))
          {
            return FieldType::BYTE;
          }
          else if(type->Equals(Internal::DotNetTypes::ShortType))
          {
            return FieldType::SHORT;
          }
          else if(type->Equals(Internal::DotNetTypes::LongType))
          {
            return FieldType::LONG;
          }
          else if(type->Equals(Internal::DotNetTypes::ByteArrayType))
          {
            return FieldType::BYTE_ARRAY;
          }
          else if(type->Equals(Internal::DotNetTypes::DoubleArrayType))
          {
            return FieldType::DOUBLE_ARRAY;
          }
          else if(type->Equals(Internal::DotNetTypes::FloatArrayType))
          {
            return FieldType::FLOAT_ARRAY;
          }
          else if(type->Equals(Internal::DotNetTypes::ShortArrayType))
          {
            return FieldType::SHORT_ARRAY;
          }
          else if(type->Equals(Internal::DotNetTypes::IntArrayType))
          {
            return FieldType::INT_ARRAY;
          }
          else if(type->Equals(Internal::DotNetTypes::LongArrayType))
          {
            return FieldType::LONG_ARRAY;
          }
          else if(type->Equals(Internal::DotNetTypes::BoolArrayType))
          {
            return FieldType::BOOLEAN_ARRAY;
          }
          else if(type->Equals(Internal::DotNetTypes::CharArrayType))
          {
            return FieldType::CHAR_ARRAY;
          }
          else if(type->Equals(Internal::DotNetTypes::StringArrayType))
          {
            return FieldType::STRING_ARRAY;
          }
          else if(type->Equals(Internal::DotNetTypes::DateType))
          {
            return FieldType::DATE;
          }
          else if(type->Equals(Internal::DotNetTypes::ByteArrayOfArrayType))
          {
            return FieldType::ARRAY_OF_BYTE_ARRAYS;
          }
          /*else if(type->Equals(Internal::DotNetTypes::ObjectArrayType))
          {
            //Giving more preference to arraylist instead of Object[] in java side
            //return this->WriteObjectArray(fieldName, safe_cast<System::Collections::Generic::List<Object^>^>(fieldValue));
            return FieldType::OBJECT_ARRAY;
          }*/
          else
          {
            return FieldType::OBJECT;
            //throw gcnew IllegalStateException("WriteField unable to serialize  " 
							//																	+ fieldName + " of " + type); 
          }
        }

       
      } // end namespace Generic
    }
  }
}