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

using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;

#pragma warning disable 618

namespace Apache.Geode.Client.UnitTests
{
  using NUnit.Framework;
  using Apache.Geode.DUnitFramework;
  using Apache.Geode.Client.Tests;
  using Apache.Geode.Client;
  using DeltaEx = Apache.Geode.Client.Tests.DeltaEx;

  namespace failing
  {
    public class CqDeltaListener<TKey, TResult> : ICqListener<TKey, TResult>
    {

      public CqDeltaListener()
      {
        m_deltaCount = 0;
        m_valueCount = 0;
      }

      public void OnEvent(CqEvent<TKey, TResult> aCqEvent)
      {
        byte[] deltaValue = aCqEvent.getDeltaValue();
        DeltaTestImpl newValue = new DeltaTestImpl();
        DataInput input = CacheHelper.DCache.CreateDataInput(deltaValue);
        newValue.FromDelta(input);
        if (newValue.GetIntVar() == 5)
        {
          m_deltaCount++;
        }
        DeltaTestImpl fullObject = (DeltaTestImpl)(object)aCqEvent.getNewValue();
        if (fullObject.GetIntVar() == 5)
        {
          m_valueCount++;
        }

      }

      public void OnError(CqEvent<TKey, TResult> aCqEvent)
      {
      }

      public void Close()
      {
      }

      public int GetDeltaCount()
      {
        return m_deltaCount;
      }

      public int GetValueCount()
      {
        return m_valueCount;
      }

      private int m_deltaCount;
      private int m_valueCount;
    }

    public class DeltaTestAD : IDelta, IDataSerializable
    {
      private int _deltaUpdate;
      private string _staticData;

      public static DeltaTestAD Create()
      {
        return new DeltaTestAD();
      }

      public DeltaTestAD()
      {
        _deltaUpdate = 1;
        _staticData = "Data which don't get updated";
      }


      #region IDelta Members

      public void FromDelta(DataInput input)
      {
        _deltaUpdate = input.ReadInt32();
      }

      public bool HasDelta()
      {
        _deltaUpdate++;
        bool isDelta = (_deltaUpdate % 2) == 1;
        Util.Log("In DeltaTestAD.HasDelta _deltaUpdate:" + _deltaUpdate + " : isDelta:" + isDelta);
        return isDelta;
      }

      public void ToDelta(DataOutput output)
      {
        output.WriteInt32(_deltaUpdate);
      }

      #endregion

      #region IDataSerializable Members

      public void FromData(DataInput input)
      {
        _deltaUpdate = input.ReadInt32();
        _staticData = input.ReadUTF();
      }

      public UInt64 ObjectSize
      {
        get { return (uint)(4 + _staticData.Length); }
      }

      public void ToData(DataOutput output)
      {
        output.WriteInt32(_deltaUpdate);
        output.WriteUTF(_staticData);
      }

      public int DeltaUpdate
      {
        get { return _deltaUpdate; }
        set { _deltaUpdate = value; }
      }

      #endregion
    }

    [TestFixture]
    [Category("group1")]
    [Category("unicast_only")]
    [Category("generics")]
    public class ThinClientDeltaTest : ThinClientRegionSteps
    {
      #region Private members

      private UnitProcess m_client1, m_client2;
      private CqDeltaListener<object, DeltaTestImpl> myCqListener;

      #endregion

      protected override ClientBase[] GetClients()
      {
        m_client1 = new UnitProcess();
        m_client2 = new UnitProcess();
        return new ClientBase[] { m_client1, m_client2 };
      }

      [TestFixtureTearDown]
      public override void EndTests()
      {
        CacheHelper.StopJavaServers();
        base.EndTests();
      }

      [TearDown]
      public override void EndTest()
      {
        try
        {
          CacheHelper.ClearEndpoints();
          CacheHelper.ClearLocators();
        }
        finally
        {
          CacheHelper.StopJavaServers();
          CacheHelper.StopJavaLocators();
        }
        base.EndTest();
      }

      public void createLRURegionAndAttachPool(string regionName, string poolName)
      {
        CacheHelper.CreateLRUTCRegion_Pool<object, object>(regionName, true, true, null, null, poolName, false, 3);
      }

      public void createRegionAndAttachPool(string regionName, string poolName, bool cloningEnabled)
      {
        CacheHelper.CreateTCRegion_Pool<object, object>(regionName, true, true, null, null, poolName, false,
          false, cloningEnabled);
      }

      public void createPool(string name, string locators, string serverGroup,
        int redundancy, bool subscription)
      {
        CacheHelper.CreatePool<object, object>(name, locators, serverGroup, redundancy, subscription);
      }

      void DoNotificationWithDelta()
      {
        try
        {
          CacheHelper.DCache.TypeRegistry.RegisterType(DeltaEx.create, 1);
        }
        catch (IllegalStateException)
        {
          //do nothig.
        }

        string cKey = m_keys[0];
        DeltaEx val = new DeltaEx();
        IRegion<object, object> reg = CacheHelper.GetRegion<object, object>("DistRegionAck");
        reg[cKey] = val;
        val.SetDelta(true);
        reg[cKey] = val;

        string cKey1 = m_keys[1];
        DeltaEx val1 = new DeltaEx();
        reg[cKey1] = val1;
        val1.SetDelta(true);
        reg[cKey1] = val1;
        DeltaEx.ToDeltaCount = 0;
        DeltaEx.ToDataCount = 0;
      }

      void DoNotificationWithDefaultCloning()
      {
        string cKey = m_keys[0];
        DeltaTestImpl val = new DeltaTestImpl();
        IRegion<object, object> reg = CacheHelper.GetRegion<object, object>("DistRegionAck");
        reg[cKey] = val;
        val.SetIntVar(2);
        val.SetDelta(true);
        reg[cKey] = val;

        javaobject.PdxDelta pd = new javaobject.PdxDelta(1001);
        for (int i = 0; i < 10; i++)
        {
          reg["pdxdelta"] = pd;
        }
      }

      void DoNotificationWithDeltaLRU()
      {
        try
        {
          CacheHelper.DCache.TypeRegistry.RegisterType(DeltaEx.create, 1);
        }
        catch (IllegalStateException)
        {
          //do nothig.
        }

        string cKey1 = "key1";
        string cKey2 = "key2";
        string cKey3 = "key3";
        string cKey4 = "key4";
        string cKey5 = "key5";
        string cKey6 = "key6";
        DeltaEx val1 = new DeltaEx();
        DeltaEx val2 = new DeltaEx();
        IRegion<object, object> reg = CacheHelper.GetRegion<object, object>("DistRegionAck");
        reg[cKey1] = val1;
        reg[cKey2] = val1;
        reg[cKey3] = val1;
        reg[cKey4] = val1;
        reg[cKey5] = val1;
        reg[cKey6] = val1;
        val2.SetDelta(true);
        reg[cKey1] = val2;

        DeltaEx.ToDeltaCount = 0;
        DeltaEx.ToDataCount = 0;
      }

      void DoExpirationWithDelta()
      {
        try
        {
          CacheHelper.DCache.TypeRegistry.RegisterType(DeltaEx.create, 1);
        }
        catch (IllegalStateException)
        {
          //do nothig.
        }

        DeltaEx val1 = new DeltaEx();
        IRegion<object, object> reg = CacheHelper.GetRegion<object, object>("DistRegionAck");
        reg[1] = val1;
        // Sleep 10 seconds to allow expiration of entry in client 2
        Thread.Sleep(10000);
        val1.SetDelta(true);
        reg[1] = val1;
        DeltaEx.ToDeltaCount = 0;
        DeltaEx.ToDataCount = 0;
      }

      void DoCqWithDelta()
      {
        string cKey1 = "key1";
        IRegion<object, object> reg = CacheHelper.GetRegion<object, object>("DistRegionAck");
        DeltaTestImpl value = new DeltaTestImpl();
        reg[cKey1] = value;
        value.SetIntVar(5);
        value.SetDelta(true);
        reg[cKey1] = value;
      }

      void initializeDeltaClientAD()
      {
        try
        {
          CacheHelper.DCache.TypeRegistry.RegisterType(DeltaTestAD.Create, 151);
        }
        catch (IllegalStateException)
        {
          //do nothng
        }
      }

      void DoDeltaAD_C1_1()
      {
        DeltaTestAD val = new DeltaTestAD();
        IRegion<object, object> reg = CacheHelper.GetRegion<object, object>("DistRegionAck");
        reg.GetSubscriptionService().RegisterAllKeys();
        Util.Log("clientAD1 put");
        reg[1] = val;
        Util.Log("clientAD1 put done");
      }

      void DoDeltaAD_C2_1()
      {
        IRegion<object, object> reg = CacheHelper.GetRegion<object, object>("DistRegionAck");

        Util.Log("clientAD2 get");
        DeltaTestAD val = (DeltaTestAD)reg[1];

        Assert.AreEqual(2, val.DeltaUpdate);
        Util.Log("clientAD2 get done");
        reg[1] = val;
        Util.Log("clientAD2 put done");

        javaobject.PdxDelta pd = new javaobject.PdxDelta(1001);
        for (int i = 0; i < 10; i++)
        {
          reg["pdxdelta"] = pd;
        }
      }

      void DoDeltaAD_C1_afterC2Put()
      {
        Thread.Sleep(15000);
        DeltaTestAD val = null;
        IRegion<object, object> reg = CacheHelper.GetRegion<object, object>("DistRegionAck");
        Util.Log("client fetching entry from local cache");
        val = (DeltaTestAD)reg.GetEntry(1).Value;
        Assert.IsNotNull(val);
        Assert.AreEqual(3, val.DeltaUpdate);
        Util.Log("done");

        System.Threading.Thread.Sleep(5000);
        //Assert.Greater(javaobject.PdxDelta.GotDelta, 7, "this should have received delta");
        javaobject.PdxDelta pd = (javaobject.PdxDelta)(reg.GetLocalView()["pdxdelta"]);
        Assert.Greater(pd.Delta, 7, "this should have received delta");
      }

      void runDeltaWithAppdomian(bool cloningenable)
      {
        CacheHelper.SetupJavaServers(true, "cacheserver_with_deltaAD.xml");
        CacheHelper.StartJavaLocator(1, "GFELOC1");
        CacheHelper.StartJavaServerWithLocators(1, "GFECS5", 1);
        string regionName = "DistRegionAck";
        // if (usePools)
        {
          //CacheHelper.CreateTCRegion_Pool_AD("DistRegionAck", false, false, null, null, CacheHelper.Locators, "__TEST_POOL1__", false, false, false);
          m_client1.Call(CacheHelper.CreateTCRegion_Pool_AD1, regionName, false, true, CacheHelper.Locators, (string)"__TEST_POOL1__", true, cloningenable);
          m_client2.Call(CacheHelper.CreateTCRegion_Pool_AD1, regionName, false, true, CacheHelper.Locators, (string)"__TEST_POOL1__", false, cloningenable);

          // m_client1.Call(createPool, "__TEST_POOL1__", CacheHelper.Locators, (string)null, 0, false);
          // m_client1.Call(createRegionAndAttachPool, "DistRegionAck", "__TEST_POOL1__");
        }


        m_client1.Call(initializeDeltaClientAD);
        m_client2.Call(initializeDeltaClientAD);

        m_client1.Call(DoDeltaAD_C1_1);
        m_client2.Call(DoDeltaAD_C2_1);
        m_client1.Call(DoDeltaAD_C1_afterC2Put);
        m_client1.Call(Close);
        m_client2.Call(Close);

        CacheHelper.StopJavaServer(1);
        CacheHelper.StopJavaLocator(1);
        CacheHelper.ClearEndpoints();
        CacheHelper.ClearLocators();
      }

      void registerClassCl2()
      {
        try
        {
          CacheHelper.DCache.TypeRegistry.RegisterType(DeltaEx.create, 1);
        }
        catch (IllegalStateException)
        {
          //do nothing
        }
        IRegion<object, object> reg = CacheHelper.GetRegion<object, object>("DistRegionAck");

        reg.GetSubscriptionService().RegisterRegex(".*");
        AttributesMutator<object, object> attrMutator = reg.AttributesMutator;
        attrMutator.SetCacheListener(new SimpleCacheListener<object, object>());
      }

      void registerClassDeltaTestImpl()
      {
        try
        {
          CacheHelper.DCache.TypeRegistry.RegisterType(DeltaTestImpl.CreateDeserializable, 0x1E);
        }
        catch (IllegalStateException)
        {
          // ARB: ignore exception caused by type reregistration.
        }
        DeltaTestImpl.ResetDataCount();

        Thread.Sleep(2000);
        IRegion<object, object> reg = CacheHelper.GetRegion<object, object>("DistRegionAck");
        try
        {
          reg.GetSubscriptionService().RegisterRegex(".*");
        }
        catch (Exception)
        {
          // ARB: ignore regex exception for missing notification channel.
        }
      }

      void registerCq()
      {
        Pool thePool = CacheHelper.DCache.GetPoolManager().Find("__TEST_POOL1__");
        QueryService cqService = null;
        cqService = thePool.GetQueryService();
        CqAttributesFactory<object, DeltaTestImpl> attrFac = new CqAttributesFactory<object, DeltaTestImpl>();
        myCqListener = new CqDeltaListener<object, DeltaTestImpl>();
        attrFac.AddCqListener(myCqListener);
        CqAttributes<object, DeltaTestImpl> cqAttr = attrFac.Create();
        CqQuery<object, DeltaTestImpl> theQuery = cqService.NewCq("select * from /DistRegionAck d where d.intVar > 4", cqAttr, false);
        theQuery.Execute();
      }

      void VerifyDeltaCount()
      {
        Thread.Sleep(1000);
        Util.Log("Total Data count" + DeltaEx.FromDataCount);
        Util.Log("Total Data count" + DeltaEx.FromDeltaCount);
        if (DeltaEx.FromDataCount != 3)
          Assert.Fail("Count of fromData called should be 3 ");
        if (DeltaEx.FromDeltaCount != 2)
          Assert.Fail("Count of fromDelta called should be 2 ");
        if (SimpleCacheListener<object, object>.isSuccess == false)
          Assert.Fail("Listener failure");
        SimpleCacheListener<object, object>.isSuccess = false;
        if (DeltaEx.CloneCount != 2)
          Assert.Fail("Clone count should be 2, is " + DeltaEx.CloneCount);

        DeltaEx.FromDataCount = 0;
        DeltaEx.FromDeltaCount = 0;
        DeltaEx.CloneCount = 0;
      }

      void VerifyCloning()
      {
        Thread.Sleep(1000);
        string cKey = m_keys[0];
        IRegion<object, object> reg = CacheHelper.GetRegion<object, object>("DistRegionAck");
        DeltaTestImpl val = reg[cKey] as DeltaTestImpl;

        if (val.GetIntVar() != 2)
          Assert.Fail("Int value after cloning should be 2, is " + val.GetIntVar());
        if (DeltaTestImpl.GetFromDataCount() != 2)
          Assert.Fail("After cloning, fromDataCount should have been 2, is " + DeltaTestImpl.GetFromDataCount());
        if (DeltaTestImpl.GetToDataCount() != 1)
          Assert.Fail("After cloning, toDataCount should have been 1, is " + DeltaTestImpl.GetToDataCount());

        System.Threading.Thread.Sleep(5000);
        //Assert.Greater(javaobject.PdxDelta.GotDelta, 7, "this should have received delta");
        javaobject.PdxDelta pd = (javaobject.PdxDelta)(reg.GetLocalView()["pdxdelta"]);
        Assert.Greater(pd.Delta, 7, "this should have received delta");
      }

      void VerifyDeltaCountLRU()
      {
        Thread.Sleep(1000);
        if (DeltaEx.FromDataCount != 8)
        {
          Util.Log("DeltaEx.FromDataCount = " + DeltaEx.FromDataCount);
          Util.Log("DeltaEx.FromDeltaCount = " + DeltaEx.FromDeltaCount);
          Assert.Fail("Count should have been 8. 6 for common put and two when pulled from database and deserialized");
        }
        if (DeltaEx.FromDeltaCount != 1)
        {
          Util.Log("DeltaEx.FromDeltaCount = " + DeltaEx.FromDeltaCount);
          Assert.Fail("Count should have been 1");
        }
        DeltaEx.FromDataCount = 0;
        DeltaEx.FromDeltaCount = 0;
      }

      void VerifyCqDeltaCount()
      {
        // Wait for Cq event processing in listener
        Thread.Sleep(1000);
        if (myCqListener.GetDeltaCount() != 1)
        {
          Assert.Fail("Delta from CQ event does not have expected value");
        }
        if (myCqListener.GetValueCount() != 1)
        {
          Assert.Fail("Value from CQ event is incorrect");
        }
      }
      void VerifyExpirationDeltaCount()
      {
        Thread.Sleep(1000);
        if (DeltaEx.FromDataCount != 2)
          Assert.Fail("Count should have been 2.");
        if (DeltaEx.FromDeltaCount != 0)
          Assert.Fail("Count should have been 0.");
        DeltaEx.FromDataCount = 0;
        DeltaEx.FromDeltaCount = 0;
      }

      void runNotificationWithDelta()
      {
        CacheHelper.SetupJavaServers(true, "cacheserver_with_delta.xml");
        CacheHelper.StartJavaLocator(1, "GFELOC1");
        CacheHelper.StartJavaServerWithLocators(1, "GFECS5", 1);

        m_client1.Call(createPool, "__TEST_POOL1__", CacheHelper.Locators, (string)null, 0, true);
        m_client1.Call(createRegionAndAttachPool, "DistRegionAck", "__TEST_POOL1__", true);

        m_client2.Call(createPool, "__TEST_POOL1__", CacheHelper.Locators, (string)null, 0, true);
        m_client2.Call(createRegionAndAttachPool, "DistRegionAck", "__TEST_POOL1__", true);

        m_client2.Call(registerClassCl2);

        m_client1.Call(DoNotificationWithDelta);
        m_client2.Call(VerifyDeltaCount);
        m_client1.Call(Close);
        m_client2.Call(Close);

        CacheHelper.StopJavaServer(1);
        CacheHelper.StopJavaLocator(1);
        CacheHelper.ClearEndpoints();
        CacheHelper.ClearLocators();
      }

      void runNotificationWithDefaultCloning()
      {
        CacheHelper.SetupJavaServers(true, "cacheserver_with_delta_test_impl.xml");
        CacheHelper.StartJavaLocator(1, "GFELOC1");
        CacheHelper.StartJavaServerWithLocators(1, "GFECS5", 1);

        m_client1.Call(createPool, "__TEST_POOL1__", CacheHelper.Locators, (string)null, 0, true);
        m_client1.Call(createRegionAndAttachPool, "DistRegionAck", "__TEST_POOL1__", true);

        m_client2.Call(createPool, "__TEST_POOL1__", CacheHelper.Locators, (string)null, 0, true);
        m_client2.Call(createRegionAndAttachPool, "DistRegionAck", "__TEST_POOL1__", true);

        m_client1.Call(registerClassDeltaTestImpl);
        m_client2.Call(registerClassDeltaTestImpl);

        m_client1.Call(DoNotificationWithDefaultCloning);
        m_client2.Call(VerifyCloning);
        m_client1.Call(Close);
        m_client2.Call(Close);

        CacheHelper.StopJavaServer(1);
        CacheHelper.StopJavaLocator(1);
        CacheHelper.ClearEndpoints();
        CacheHelper.ClearLocators();
      }

      void runNotificationWithDeltaWithOverFlow()
      {
        CacheHelper.SetupJavaServers(true, "cacheserver_with_delta.xml");
        CacheHelper.StartJavaLocator(1, "GFELOC1");
        CacheHelper.StartJavaServerWithLocators(1, "GFECS1", 1);

        m_client1.Call(createPool, "__TEST_POOL1__", CacheHelper.Locators, (string)null, 0, true);
        m_client1.Call(createLRURegionAndAttachPool, "DistRegionAck", "__TEST_POOL1__");

        m_client2.Call(createPool, "__TEST_POOL1__", CacheHelper.Locators, (string)null, 0, true);
        m_client2.Call(createLRURegionAndAttachPool, "DistRegionAck", "__TEST_POOL1__");

        m_client2.Call(registerClassCl2);

        m_client1.Call(DoNotificationWithDeltaLRU);
        m_client2.Call(VerifyDeltaCountLRU);
        m_client1.Call(Close);
        m_client2.Call(Close);
        CacheHelper.StopJavaServer(1);
        CacheHelper.StopJavaLocator(1);
        CacheHelper.ClearEndpoints();
        CacheHelper.ClearLocators();
      }

      //#region Tests
      
      [Test]
      public void PutWithDeltaADWithCloning()
      {
        runDeltaWithAppdomian(true);
      }

      [Test]
      public void NotificationWithDelta()
      {
        runNotificationWithDelta();
      }

      [Test]
      public void NotificationWithDefaultCloning()
      {
        runNotificationWithDefaultCloning();
      }

      [Test]
      public void NotificationWithDeltaWithOverFlow()
      {
        runNotificationWithDeltaWithOverFlow();
      }

      //#endregion
    }
  }
}

