#pragma once

#ifndef GEODE_INTEGRATION_TEST_THINCLIENTDISTOPS2_H_
#define GEODE_INTEGRATION_TEST_THINCLIENTDISTOPS2_H_

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

#include "fw_dunit.hpp"
#include <ace/OS.h>

#include <string>
#include <vector>

#define ROOT_NAME "ThinClientDistOps2"
#define ROOT_SCOPE DISTRIBUTED_ACK

#include "ThinClientHelper.hpp"


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

using apache::geode::client::CacheableInt32;
using apache::geode::client::CacheableInt64;
using apache::geode::client::CacheableKey;
using apache::geode::client::CacheableString;
using apache::geode::client::CacheHelper;
using apache::geode::client::CacheServerException;
using apache::geode::client::EntryExistsException;
using apache::geode::client::IllegalArgumentException;
using apache::geode::client::Properties;

static bool isLocalServer = false;
static bool isLocator = false;
static int numberOfLocators = 0;
const char* poolName = "__TEST_POOL1__";

const char* locatorsG =
    CacheHelper::getLocatorHostPort(isLocator, isLocalServer, numberOfLocators);

#include "LocatorHelper.hpp"

#define verifyEntry(a, b, c, d) _verifyEntry(a, b, c, d, __LINE__)

void _verifyEntry(const std::string& name, const char* key, const char* val,
                  bool checkLocal, int line) {
  char logmsg[1024];
  sprintf(logmsg, "verifyEntry() called from %d.\n", line);
  LOG(logmsg);
  _verifyEntry(name, key, val, false, checkLocal);
  LOG("Entry verified.");
}

const char* _keys[] = {"Key-1", "Key-2", "Key-3", "Key-4"};
const char* _vals[] = {"Value-1", "Value-2", "Value-3", "Value-4"};
const char* _nvals[] = {"New Value-1", "New Value-2", "New Value-3",
                        "New Value-4"};

const char* _regionNames[] = {"DistRegionAck", "DistRegionNoAck"};

DUNIT_TASK_DEFINITION(SERVER1, CreateServer1)
  {
    if (isLocalServer) CacheHelper::initServer(1);
    LOG("SERVER1 started");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(SERVER2, CreateServer2And3)
  {
    if (isLocalServer) CacheHelper::initServer(2);
    if (isLocalServer) CacheHelper::initServer(3);
    LOG("SERVER23 started");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(SERVER2, CreateServer2And3_Locator)
  {
    if (isLocalServer) CacheHelper::initServer(2, nullptr, locatorsG);
    if (isLocalServer) CacheHelper::initServer(3, nullptr, locatorsG);
    LOG("SERVER23 started");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT1, CreateClient1Regions_Pooled_Locator)
  {
    initClientWithPool(true, "__TEST_POOL1__", locatorsG, nullptr, nullptr, 0,
                       true);
    createPooledRegion(_regionNames[0], USE_ACK, locatorsG, poolName);
    createPooledRegion(_regionNames[1], NO_ACK, locatorsG, poolName);
    LOG("CreateClient1Regions complete.");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT2, CreateClient2Regions_Pooled_Locator)
  {
    initClientWithPool(true, "__TEST_POOL1__", locatorsG, nullptr, nullptr, 0,
                       true);
    createPooledRegion(_regionNames[0], USE_ACK, locatorsG, poolName);
    createPooledRegion(_regionNames[1], NO_ACK, locatorsG, poolName);
    LOG("CreateClient1Regions complete.");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT1, CreateClient1Entries)
  {
    createEntry(_regionNames[0], _keys[0], _vals[0]);
    createEntry(_regionNames[1], _keys[2], _vals[2]);
    LOG("CreateClient1Entries complete.");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT2, CreateClient2Entries)
  {
    doNetsearch(_regionNames[0], _keys[0], _vals[0]);
    doNetsearch(_regionNames[1], _keys[2], _vals[2]);
    createEntry(_regionNames[0], _keys[1], _vals[1]);
    createEntry(_regionNames[1], _keys[3], _vals[3]);
    LOG("CreateClient2Entries complete.");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT1, UpdateClient1Entry)
  {
    doNetsearch(_regionNames[0], _keys[1], _vals[1]);
    doNetsearch(_regionNames[1], _keys[3], _vals[3]);
    updateEntry(_regionNames[0], _keys[0], _nvals[0]);
    updateEntry(_regionNames[1], _keys[2], _nvals[2]);
    LOG("UpdateClient1Entry complete.");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT2, UpdateClient2Entry)
  {
    doNetsearch(_regionNames[0], _keys[0], _vals[0], false);
    doNetsearch(_regionNames[1], _keys[2], _vals[2], false);
    updateEntry(_regionNames[0], _keys[1], _nvals[1]);
    updateEntry(_regionNames[1], _keys[3], _nvals[3]);
    LOG("UpdateClient2Entry complete.");
  }
END_TASK_DEFINITION

// Test for getAll
DUNIT_TASK_DEFINITION(CLIENT1, Client1GetAll)
  {
    auto reg0 = getHelper()->getRegion(_regionNames[0]);

    std::vector<std::shared_ptr<CacheableKey>> keys0;
    auto key0 = CacheableString::create(_keys[0]);
    auto key1 = CacheableString::create(_keys[1]);

    // re-create region with caching enabled
    reg0->localDestroyRegion();
    reg0 = nullptr;
    getHelper()->createPooledRegion(regionNames[0], USE_ACK, nullptr,
                                    "__TEST_POOL1__", true, true);
    reg0 = getHelper()->getRegion(_regionNames[0]);
    // check for IllegalArgumentException for empty key list
    keys0.clear();
    try {
      reg0->getAll(keys0);
      FAIL("Expected IllegalArgumentException");
    } catch (const IllegalArgumentException&) {
      LOG("Got expected IllegalArgumentException");
    }

    keys0.push_back(key0);
    keys0.push_back(key1);
    {
      auto values = reg0->getAll(keys0);
      ASSERT(values.size() == 2, "Expected 2 values");
      auto val0 = std::dynamic_pointer_cast<CacheableString>(values[key0]);
      auto val1 = std::dynamic_pointer_cast<CacheableString>(values[key1]);
      ASSERT(strcmp(_nvals[0], val0->value().c_str()) == 0,
             "Got unexpected value");
      ASSERT(strcmp(_nvals[1], val1->value().c_str()) == 0,
             "Got unexpected value");
    }

    // for second region invalidate only one key to have a partial get
    // from java server
    auto reg1 = getHelper()->getRegion(_regionNames[1]);
    auto key2 = CacheableString::create(_keys[2]);
    auto key3 = CacheableString::create(_keys[3]);
    reg1->localInvalidate(key2);
    std::vector<std::shared_ptr<CacheableKey>> keys1;
    keys1.push_back(key2);
    keys1.push_back(key3);

    {
      auto values = reg1->getAll(keys1);
      ASSERT(values.size() == 2, "Expected 2 values");
      auto val2 = std::dynamic_pointer_cast<CacheableString>(values[key2]);
      auto val3 = std::dynamic_pointer_cast<CacheableString>(values[key3]);
      ASSERT(strcmp(_nvals[2], val2->value().c_str()) == 0,
             "Got unexpected value");
      ASSERT(strcmp(_vals[3], val3->value().c_str()) == 0,
             "Got unexpected value");
    }

    // also check that the region is properly populated
    ASSERT(reg1->size() == 2, "Expected 2 entries in the region");
    auto regEntries = reg1->entries(false);
    ASSERT(regEntries.size() == 2, "Expected 2 entries in the region.entries");
    verifyEntry(_regionNames[1], _keys[2], _nvals[2], true);
    verifyEntry(_regionNames[1], _keys[3], _vals[3], true);

    // also check with nullptr values that region is properly populated
    {
      reg1->localInvalidate(key3);
      auto values = reg1->getAll(keys1);
      // now check that the region is properly populated
      ASSERT(reg1->size() == 2, "Expected 2 entries in the region");
      regEntries = reg1->entries(false);
      ASSERT(regEntries.size() == 2,
             "Expected 2 entries in the region.entries");
      verifyEntry(_regionNames[1], _keys[2], _nvals[2], true);
      verifyEntry(_regionNames[1], _keys[3], _nvals[3], true);
    }
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT1, Client1GetAll_Pool)
  {
    {
      auto reg0 = getHelper()->getRegion(_regionNames[0]);

      std::vector<std::shared_ptr<CacheableKey>> keys0;
      auto key0 = CacheableString::create(_keys[0]);
      auto key1 = CacheableString::create(_keys[1]);

      getHelper()->createRegionAndAttachPool(_regionNames[0], USE_ACK,
                                             poolName);
      reg0 = getHelper()->getRegion(_regionNames[0]);
      // check for IllegalArgumentException for empty key list
      keys0.clear();
      try {
        reg0->getAll(keys0);
        FAIL("Expected IllegalArgumentException");
      } catch (const IllegalArgumentException&) {
        LOG("Got expected IllegalArgumentException");
      }

      keys0.push_back(key0);
      keys0.push_back(key1);

      auto values = reg0->getAll(keys0);

      ASSERT(values.size() == 2, "Expected 2 values");
      auto val0 = std::dynamic_pointer_cast<CacheableString>(values[key0]);
      auto val1 = std::dynamic_pointer_cast<CacheableString>(values[key1]);
      ASSERT(strcmp(_nvals[0], val0->value().c_str()) == 0,
             "Got unexpected value");
      ASSERT(strcmp(_nvals[1], val1->value().c_str()) == 0,
             "Got unexpected value");
    }

    {
      // for second region invalidate only one key to have a partial get
      // from java server
      auto reg1 = getHelper()->getRegion(_regionNames[1]);
      auto key2 = CacheableString::create(_keys[2]);
      auto key3 = CacheableString::create(_keys[3]);
      reg1->localInvalidate(key2);
      std::vector<std::shared_ptr<CacheableKey>> keys1;
      keys1.push_back(key2);
      keys1.push_back(key3);

      auto values = reg1->getAll(keys1);

      ASSERT(values.size() == 2, "Expected 2 values");
      auto val2 = std::dynamic_pointer_cast<CacheableString>(values[key2]);
      auto val3 = std::dynamic_pointer_cast<CacheableString>(values[key3]);
      ASSERT(strcmp(_nvals[2], val2->value().c_str()) == 0,
             "Got unexpected value");
      ASSERT(strcmp(_vals[3], val3->value().c_str()) == 0,
             "Got unexpected value");

      // also check that the region is properly populated
      ASSERT(reg1->size() == 2, "Expected 2 entries in the region");
      auto regEntries = reg1->entries(false);
      ASSERT(regEntries.size() == 2,
             "Expected 2 entries in the region.entries");
      verifyEntry(_regionNames[1], _keys[2], _nvals[2], true);
      verifyEntry(_regionNames[1], _keys[3], _vals[3], true);

      // also check with nullptr values that region is properly populated
      reg1->localInvalidate(key3);

      reg1->getAll(keys1);
      // now check that the region is properly populated
      ASSERT(reg1->size() == 2, "Expected 2 entries in the region");
      regEntries = reg1->entries(false);
      ASSERT(regEntries.size() == 2,
             "Expected 2 entries in the region.entries");
      verifyEntry(_regionNames[1], _keys[2], _nvals[2], true);
      verifyEntry(_regionNames[1], _keys[3], _nvals[3], true);
    }
  }
END_TASK_DEFINITION

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

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

DUNIT_TASK_DEFINITION(SERVER1, CloseServer1)
  {
    if (isLocalServer) {
      CacheHelper::closeServer(1);
      LOG("SERVER1 stopped");
    }
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(SERVER2, CloseServer2)
  {
    if (isLocalServer) {
      CacheHelper::closeServer(2);
      LOG("SERVER2 stopped");
    }
    if (isLocalServer) {
      CacheHelper::closeServer(3);
      LOG("SERVER3 stopped");
    }
  }
END_TASK_DEFINITION

#endif  // GEODE_INTEGRATION_TEST_THINCLIENTDISTOPS2_H_
