/*
 * 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_INTEGRATION_TEST_THINCLIENTDURABLEFAILOVER_H_
#define GEODE_INTEGRATION_TEST_THINCLIENTDURABLEFAILOVER_H_

#include "fw_dunit.hpp"
#include "ThinClientHelper.hpp"

#include <thread>
#include <chrono>

/* Testing Parameters              Param's Value
Termination :                   Keepalive = true/ false, Client crash
Restart Time:                   Before Timeout / After Timeout
Register Interest               Durable/ Non Durable

Descripton:  There is One server , one feeder and two clients. Both clients
comes up ->
feeder feed -> both clients go down in same way ( keepalive = true/ false ,
crash )->
feeder feed -> Client1 comes up -> Client2 comes up after timeout -> verify ->
Shutdown

*/

#define CLIENT1 s1p1
#define CLIENT2 s1p2
#define SERVER1 s2p1
#define FEEDER s2p2

namespace { // NOLINT(google-build-namespaces)

using apache::geode::client::EntryEvent;
using apache::geode::client::Exception;
using apache::geode::client::HashMapOfCacheable;
using apache::geode::client::RegionEvent;

class OperMonitor : public CacheListener {
  int m_ops;
  HashMapOfCacheable m_map;

  void check(const EntryEvent& event) {
    m_ops++;

    auto key = event.getKey();
    std::shared_ptr<CacheableInt32> value = nullptr;
    try {
      value = std::dynamic_pointer_cast<CacheableInt32>(event.getNewValue());
    } catch (Exception&) {
      //  do nothing.
    }

    auto keyPtr = std::dynamic_pointer_cast<CacheableString>(key);
    if (keyPtr != nullptr && value != nullptr) {
      char buf[256] = {'\0'};
      sprintf(buf, " Got Key: %s, Value: %d", keyPtr->toString().c_str(),
              value->value());
      LOG(buf);
    }

    if (value) {
      m_map[key] = value;
    }
  }

 public:
  OperMonitor() : m_ops(0) {}

  ~OperMonitor() override { m_map.clear(); }

  void validate(size_t keyCount, int eventcount, int durableValue,
                int nonDurableValue) {
    LOG("validate called");
    char buf[256] = {'\0'};

    sprintf(buf, "Expected %zd keys for the region, Actual = %zd", keyCount,
            m_map.size());
    ASSERT(m_map.size() == keyCount, buf);

    sprintf(buf, "Expected %d events for the region, Actual = %d", eventcount,
            m_ops);
    ASSERT(m_ops == eventcount, buf);

    for (const auto& item : m_map) {
      auto keyPtr = std::dynamic_pointer_cast<CacheableString>(item.first);
      auto valuePtr = std::dynamic_pointer_cast<CacheableInt32>(item.second);

      if (keyPtr->toString().find('D') ==
          std::string::npos) { /*Non Durable Key */
        sprintf(buf,
                "Expected final value for nonDurable Keys = %d, Actual = %d",
                nonDurableValue, valuePtr->value());
        ASSERT(valuePtr->value() == nonDurableValue, buf);
      } else { /*Durable Key */
        sprintf(buf, "Expected final value for Durable Keys = %d, Actual = %d",
                durableValue, valuePtr->value());
        ASSERT(valuePtr->value() == durableValue, buf);
      }
    }
  }

  void afterCreate(const EntryEvent& event) override {
    LOG("afterCreate called");
    check(event);
  }

  void afterUpdate(const EntryEvent& event) override {
    LOG("afterUpdate called");
    check(event);
  }

  void afterDestroy(const EntryEvent& event) override {
    LOG("afterDestroy called");
    check(event);
  }

  void afterRegionInvalidate(const RegionEvent&) override{}

  void afterRegionDestroy(const RegionEvent&) override{}
};

void setCacheListener(const char* regName,
                      std::shared_ptr<OperMonitor> monitor) {
  auto reg = getHelper()->getRegion(regName);
  auto attrMutator = reg->getAttributesMutator();
  attrMutator->setCacheListener(monitor);
}
std::shared_ptr<OperMonitor> mon1 = nullptr;
std::shared_ptr<OperMonitor> mon2 = nullptr;

#include "ThinClientDurableInit.hpp"
#include "ThinClientTasks_C2S2.hpp"

/* Total 10 Keys , alternate durable and non-durable */
const char* mixKeys[] = {"Key-1", "D-Key-1", "L-Key", "LD-Key"};
const char* testRegex[] = {"D-Key-.*", "Key-.*"};

void initClientCache(int redundancy, int durableTimeout,
                     std::shared_ptr<OperMonitor>& mon, int sleepDuration = 0,
                     int durableIdx = 0) {
  if (sleepDuration) SLEEP(sleepDuration);

  if (mon == nullptr) {
    mon = std::make_shared<OperMonitor>();
  }

  //  35 sec ack interval to ensure primary clears its Q only
  // after the secondary comes up and is able to receive the QRM
  // otherwise it will get the unacked events from GII causing the
  // client to get 2 extra / replayed events.
  initClientAndRegion(redundancy, durableIdx, std::chrono::seconds(1),
                      std::chrono::seconds(1),
                      std::chrono::seconds(durableTimeout));

  setCacheListener(regionNames[0], mon);

  getHelper()->cachePtr->readyForEvents();

  auto regPtr0 = getHelper()->getRegion(regionNames[0]);

  // for R =1 it will get a redundancy error
  try {
    regPtr0->registerRegex(testRegex[0], true);
  } catch (Exception&) {
    //  do nothing.
  }
  try {
    regPtr0->registerRegex(testRegex[1], false);
  } catch (Exception&) {
    //  do nothing.
  }
}

void feederUpdate(int value) {
  createIntEntry(regionNames[0], mixKeys[0], value);
  std::this_thread::sleep_for(std::chrono::milliseconds(10));
  createIntEntry(regionNames[0], mixKeys[1], value);
  std::this_thread::sleep_for(std::chrono::milliseconds(10));
}

/* Close Client 1 with option keep alive = true*/
DUNIT_TASK_DEFINITION(CLIENT1, CloseClient1WithKeepAlive)
  {
    // sleep 30 sec to allow clients' periodic acks (1 sec) to go out
    // this is along with the 5 sec sleep after feeder update and
    // tied to the notify-ack-interval setting of 35 sec.
    SLEEP(30000);
    getHelper()->disconnect(true);
    cleanProc();
    LOG("CloseClient1WithKeepAlive complete: Keepalive = True");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(SERVER1, StartServer1)
  {
    if (isLocalServer) {
      CacheHelper::initServer(1, "cacheserver_notify_subscription.xml",
                              locatorsG);
    }

    LOG("SERVER started");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(SERVER1, StartServer2)
  {
    if (isLocalServer) {
      CacheHelper::initServer(2, "cacheserver_notify_subscription2.xml",
                              locatorsG);
    }

    //  sleep for 3 seconds to allow redundancy monitor to detect new server.
    std::this_thread::sleep_for(std::chrono::seconds(3));
    LOG("SERVER started");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(FEEDER, FeederInit)
  {
    initClientWithPool(true, "__TEST_POOL1__", locatorsG, nullptr, nullptr, 0,
                       true);
    getHelper()->createPooledRegion(regionNames[0], USE_ACK, locatorsG,
                                    "__TEST_POOL1__", true, true);
    LOG("FeederInit complete.");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT1, InitClient1NoRedundancy)
  { initClientCache(0, 300, mon1); }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT1, InitClient1WithRedundancy)
  { initClientCache(1, 300, mon1); }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(FEEDER, FeederUpdate1)
  {
    feederUpdate(1);

    //  Wait 5 seconds for events to be removed from ha queues.
    std::this_thread::sleep_for(std::chrono::seconds(5));

    LOG("FeederUpdate1 complete.");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(FEEDER, FeederUpdate2)
  {
    feederUpdate(2);

    //  Wait 5 seconds for events to be removed from ha queues.
    std::this_thread::sleep_for(std::chrono::seconds(5));

    LOG("FeederUpdate2 complete.");
  }
END_TASK_DEFINITION

// R =0 and clientDown, Intermediate events lost.
DUNIT_TASK_DEFINITION(CLIENT1, VerifyClientDownWithEventsLost)
  {
    LOG("Client Verify 1.");
    mon1->validate(2, 2, 1, 1);
  }
END_TASK_DEFINITION

// R =1 and clientDown, Durable events recieved
DUNIT_TASK_DEFINITION(CLIENT1, VerifyClientDownDurableEventsRecieved)
  {
    LOG("Client Verify 2.");
    mon1->validate(2, 3, 2, 1);
  }
END_TASK_DEFINITION

// No clientDown, All events recieved
DUNIT_TASK_DEFINITION(CLIENT1, VeryifyNoClientDownAllEventsReceived)
  {
    LOG("Client Verify 3.");
    mon1->validate(2, 4, 2, 2);
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(FEEDER, CloseFeeder)
  {
    cleanProc();
    LOG("FEEDER closed");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT1, CloseClient1)
  {
    mon1 = nullptr;
    cleanProc();
    LOG("CLIENT1 closed");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(SERVER1, CloseServer1)
  {
    CacheHelper::closeServer(1);
    //  Wait 2 seconds to allow client failover.
    std::this_thread::sleep_for(std::chrono::seconds(2));
    LOG("SERVER closed");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(SERVER1, CloseServer2)
  {
    CacheHelper::closeServer(2);
    LOG("SERVER closed");
  }
END_TASK_DEFINITION

void doThinClientDurableFailoverClientClosedNoRedundancy() {
  CALL_TASK(StartLocator);

  CALL_TASK(StartServer1);

  CALL_TASK(FeederInit);

  CALL_TASK(InitClient1NoRedundancy);

  CALL_TASK(StartServer2);

  CALL_TASK(FeederUpdate1);

  CALL_TASK(CloseClient1WithKeepAlive);

  CALL_TASK(CloseServer1);

  CALL_TASK(FeederUpdate2);

  CALL_TASK(InitClient1NoRedundancy);

  CALL_TASK(VerifyClientDownWithEventsLost);

  CALL_TASK(CloseClient1);
  CALL_TASK(CloseFeeder);
  CALL_TASK(CloseServer2);

  CALL_TASK(CloseLocator);
}

void doThinClientDurableFailoverClientNotClosedRedundancy() {
  CALL_TASK(StartLocator);

  CALL_TASK(StartServer1);

  CALL_TASK(FeederInit);

  CALL_TASK(InitClient1WithRedundancy);

  CALL_TASK(StartServer2);

  CALL_TASK(FeederUpdate1);

  CALL_TASK(CloseServer1);

  CALL_TASK(FeederUpdate2);

  CALL_TASK(VeryifyNoClientDownAllEventsReceived);

  CALL_TASK(CloseClient1);
  CALL_TASK(CloseFeeder);
  CALL_TASK(CloseServer2);

  CALL_TASK(CloseLocator);
}

void doThinClientDurableFailoverClientClosedRedundancy() {
  CALL_TASK(StartLocator);

  CALL_TASK(StartServer1);

  CALL_TASK(FeederInit);

  CALL_TASK(InitClient1WithRedundancy);

  CALL_TASK(StartServer2);

  CALL_TASK(FeederUpdate1);

  CALL_TASK(CloseClient1WithKeepAlive);

  CALL_TASK(CloseServer1);

  CALL_TASK(FeederUpdate2);

  CALL_TASK(InitClient1WithRedundancy);

  CALL_TASK(VerifyClientDownDurableEventsRecieved);

  CALL_TASK(CloseClient1);
  CALL_TASK(CloseFeeder);
  CALL_TASK(CloseServer2);

  CALL_TASK(CloseLocator);
}

}  // namespace

#endif  // GEODE_INTEGRATION_TEST_THINCLIENTDURABLEFAILOVER_H_
