/*
 * 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_THINCLIENTGATEWAYTEST_H_
#define GEODE_INTEGRATION_TEST_THINCLIENTGATEWAYTEST_H_

#include "fw_dunit.hpp"
#include "ThinClientHelper.hpp"
#include "TallyListener.hpp"
#include "TallyWriter.hpp"
#include "TallyLoader.hpp"

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

#include <string>

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

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

using apache::geode::client::testing::TallyListener;

class MyListener : public CacheListener {
 private:
  int m_events;

 public:
  MyListener() : CacheListener(), m_events(0) {
    LOG("MyListener contructor called");
  }

  ~MyListener() override = default;

  void afterCreate(const EntryEvent&) override { m_events++; }

  void afterUpdate(const EntryEvent&) override { m_events++; }

  void afterInvalidate(const EntryEvent&) override { m_events++; }

  void afterDestroy(const EntryEvent&) override { m_events++; }

  void afterRegionInvalidate(const RegionEvent&) override {}

  void afterRegionDestroy(const RegionEvent&) override {}

  int getNumEvents() { return m_events; }
};

void setCacheListener(const char* regName,
                      std::shared_ptr<TallyListener> regListener) {
  auto reg = getHelper()->getRegion(regName);
  auto attrMutator = reg->getAttributesMutator();
  attrMutator->setCacheListener(regListener);
}

const char* locHostPort1 = nullptr;
const char* locHostPort2 = nullptr;
DUNIT_TASK_DEFINITION(SERVER1, StartLocator1)
  {
    CacheHelper::initLocator(1, false, true, 1,
                             CacheHelper::staticLocatorHostPort2);
    locHostPort1 = CacheHelper::getstaticLocatorHostPort1();
    LOGINFO("Locator1 started");
  }
END_TASK_DEFINITION
DUNIT_TASK_DEFINITION(SERVER2, StartLocator2)
  {
    CacheHelper::initLocator(2, false, true, 2);
    locHostPort2 = CacheHelper::getstaticLocatorHostPort2();
    LOG("Locator2 started");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(SERVER1, StartServer1)
  {
    CacheHelper::initServer(1, "gateway1.xml", locHostPort1);
    LOG("SERVER1 started");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(SERVER2, StartServer2)
  {
    CacheHelper::initServer(2, "gateway2.xml", locHostPort2);
    LOG("SERVER started");
  }
END_TASK_DEFINITION
std::shared_ptr<MyListener> reg1Listener1 = nullptr;

DUNIT_TASK_DEFINITION(SERVER2, SetupClient2)
  {
    // CacheHelper ch = getHelper();
    reg1Listener1 = std::make_shared<MyListener>();
    auto regPtr = createPooledRegion("exampleRegion", false, locHostPort2,
                                     "poolName", true, reg1Listener1);
    regPtr->registerAllKeys();
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(SERVER1, SetupClient)
  {
    initClientWithPool(true, "poolName", locHostPort1, nullptr);
    auto regPtr = createRegionAndAttachPool("exampleRegion", true, nullptr);
    LOG(" region is created ");
    for (int i = 0; i < 100; i++) {
      LOG(" region is created put");
      regPtr->put(i, i);
    }

    dunit::sleep(10000);
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(SERVER2, VerifyClient2Events)
  {
    LOGINFO(" nevents = %d got", reg1Listener1->getNumEvents());
    ASSERT(reg1Listener1->getNumEvents() > 0,
           "Events should be greater than zero");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(SERVER1, CloseCache1)
  { cleanProc(); }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(SERVER2, CloseCache2)
  { cleanProc(); }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(SERVER1, StopServer1)
  {
    CacheHelper::closeServer(1);
    LOG("SERVER stopped");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(SERVER1, StopServer2)
  {
    CacheHelper::closeServer(2);
    LOG("SERVER2stopped");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(SERVER1, StopLocator1)
  {
    // stop locator
    CacheHelper::closeLocator(1);
    LOG("Locator1 stopped");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(SERVER1, StopLocator2)
  {
    CacheHelper::closeLocator(1);
    LOG("Locator2 stopped");
  }
END_TASK_DEFINITION

void runListenerInit() {
  CALL_TASK(StartLocator1);
  CALL_TASK(StartLocator2);
  CALL_TASK(StartServer1);
  CALL_TASK(StartServer2);
  CALL_TASK(SetupClient2);
  CALL_TASK(SetupClient);
  CALL_TASK(VerifyClient2Events);
  CALL_TASK(CloseCache1);
  CALL_TASK(CloseCache2);
  CALL_TASK(StopServer1);
  CALL_TASK(StopServer2);
  CALL_TASK(StopLocator1);
  CALL_TASK(StopLocator2);
}

}  // namespace

#endif  // GEODE_INTEGRATION_TEST_THINCLIENTGATEWAYTEST_H_
