/*
 * 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 "BuiltinCacheableWrappers.hpp"
#include "Utils.hpp"
#include <geode/FixedPartitionResolver.hpp>
#include <ace/OS.h>
#include <ace/High_Res_Timer.h>

#include <string>

#include "CacheHelper.hpp"

// Include these 2 headers for access to CacheImpl for test hooks.
#include "CacheImplHelper.hpp"
#include "testUtils.hpp"

#include "ThinClientHelper.hpp"

using apache::geode::client::CacheServerException;
using apache::geode::client::CacheWriterException;
using apache::geode::client::EntryEvent;
using apache::geode::client::Exception;
using apache::geode::client::FixedPartitionResolver;

const char* partitionRegionNames[] = {"R1", "R2", "R3"};
const char* partitionRegionName;

class CustomFixedPartitionResolver1 : public FixedPartitionResolver {
 public:
  CustomFixedPartitionResolver1() {}
  ~CustomFixedPartitionResolver1() override {}
  const std::string& getName() override {
    static std::string name = "CustomFixedPartitionResolver1";
    LOG("CustomFixedPartitionResolver1::getName()");
    return name;
  }

  std::shared_ptr<CacheableKey> getRoutingObject(
      const EntryEvent& opDetails) override {
    LOG("CustomFixedPartitionResolver1::getRoutingObject()");
    int32_t key = atoi(opDetails.getKey()->toString().c_str());
    int32_t newKey = key + 5;
    return CacheableKey::create(newKey);
  }

  const std::string& getPartitionName(const EntryEvent& opDetails) override {
    LOG("CustomFixedPartitionResolver1::getPartitionName()");
    int32_t key = atoi(opDetails.getKey()->toString().c_str());
    int32_t newkey = key % 6;
    if (newkey == 0) {
      static std::string P1 = "P1";
      return P1;
    } else if (newkey == 1) {
      static std::string P2 = "P2";
      return P2;
    } else if (newkey == 2) {
      static std::string P3 = "P3";
      return P3;
    } else if (newkey == 3) {
      static std::string P4 = "P4";
      return P4;
    } else if (newkey == 4) {
      static std::string P5 = "P5";
      return P5;
    } else if (newkey == 5) {
      static std::string P6 = "P6";
      return P6;
    } else {
      static std::string Invalid = "Invalid";
      return Invalid;
    }
  }
};
auto cptr1 = std::make_shared<CustomFixedPartitionResolver1>();

class CustomFixedPartitionResolver2 : public FixedPartitionResolver {
 public:
  CustomFixedPartitionResolver2() {}
  ~CustomFixedPartitionResolver2() override {}
  const std::string& getName() override {
    static std::string name = "CustomFixedPartitionResolver2";
    LOG("CustomFixedPartitionResolver2::getName()");
    return name;
  }

  std::shared_ptr<CacheableKey> getRoutingObject(
      const EntryEvent& opDetails) override {
    LOG("CustomFixedPartitionResolver2::getRoutingObject()");
    int32_t key = atoi(opDetails.getKey()->toString().c_str());
    int32_t newKey = key + 4;
    return CacheableKey::create(newKey /*key*/);
  }

  const std::string& getPartitionName(const EntryEvent& opDetails) override {
    LOG("CustomFixedPartitionResolver2::getPartitionName()");
    int32_t key = atoi(opDetails.getKey()->toString().c_str());
    int32_t newkey = key % 6;
    if (newkey == 0) {
      static std::string P1 = "P1";
      return P1;
    } else if (newkey == 1) {
      static std::string P2 = "P2";
      return P2;
    } else if (newkey == 2) {
      static std::string P3 = "P3";
      return P3;
    } else if (newkey == 3) {
      static std::string P4 = "P4";
      return P4;
    } else if (newkey == 4) {
      static std::string P5 = "P5";
      return P5;
    } else if (newkey == 5) {
      static std::string P6 = "P6";
      return P6;
    } else {
      static std::string Invalid = "Invalid";
      return Invalid;
    }
  }
};
auto cptr2 = std::make_shared<CustomFixedPartitionResolver2>();

class CustomFixedPartitionResolver3 : public FixedPartitionResolver {
 public:
  CustomFixedPartitionResolver3() {}
  ~CustomFixedPartitionResolver3() override {}
  const std::string& getName() override {
    static std::string name = "CustomFixedPartitionResolver3";
    LOG("CustomFixedPartitionResolver3::getName()");
    return name;
  }

  std::shared_ptr<CacheableKey> getRoutingObject(
      const EntryEvent& opDetails) override {
    LOG("CustomFixedPartitionResolver3::getRoutingObject()");
    int32_t key = atoi(opDetails.getKey()->toString().c_str());
    int32_t newKey = key % 5;
    return CacheableKey::create(newKey /*key*/);
  }

  const std::string& getPartitionName(const EntryEvent& opDetails) override {
    LOG("CustomFixedPartitionResolver3::getPartitionName()");
    int32_t key = atoi(opDetails.getKey()->toString().c_str());
    int32_t newkey = key % 3;
    if (newkey == 0) {
      static std::string P1 = "P1";
      return P1;
    } else if (newkey == 1) {
      static std::string P2 = "P2";
      return P2;
    } else if (newkey == 2) {
      static std::string P3 = "P3";
      return P3;
    } else {
      static std::string Invalid = "Invalid";
      return Invalid;
    }
  }
};
auto cptr3 = std::make_shared<CustomFixedPartitionResolver3>();

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

bool isLocalServer = false;

static bool isLocator = false;
const char* locatorsG =
    CacheHelper::getLocatorHostPort(isLocator, isLocalServer, 1);

std::vector<char*> storeEndPoints(const char* points) {
  std::vector<char*> endpointNames;
  if (points != nullptr) {
    char* ep = strdup(points);
    char* token = strtok(ep, ",");
    while (token) {
      endpointNames.push_back(token);
      token = strtok(nullptr, ",");
    }
  }
  ASSERT(endpointNames.size() == 3, "There should be 3 end points");
  return endpointNames;
}

DUNIT_TASK_DEFINITION(CLIENT1, SetRegion1)
  { partitionRegionName = partitionRegionNames[0]; }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT1, SetRegion2)
  { partitionRegionName = partitionRegionNames[1]; }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT1, SetRegion3)
  { partitionRegionName = partitionRegionNames[2]; }
END_TASK_DEFINITION

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

DUNIT_TASK_DEFINITION(SERVER2, CreateServer2)
  {
    if (isLocalServer) CacheHelper::initServer(2, "cacheserver2_fpr.xml");
    LOG("SERVER2 started");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(SERVER3, CreateServer3)
  {
    if (isLocalServer) CacheHelper::initServer(3, "cacheserver3_fpr.xml");
    LOG("SERVER3 started");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT1, StepOne_Pooled_Locator)
  {
    initClient(true);

    getHelper()->createPoolWithLocators("__TEST_POOL1__", locatorsG);
    getHelper()->createRegionAndAttachPool2(partitionRegionNames[0], USE_ACK,
                                            "__TEST_POOL1__", cptr1);
    getHelper()->createRegionAndAttachPool2(partitionRegionNames[1], USE_ACK,
                                            "__TEST_POOL1__", cptr2);
    getHelper()->createRegionAndAttachPool2(partitionRegionNames[2], USE_ACK,
                                            "__TEST_POOL1__", cptr3);

    LOG("StepOne_Pooled_Locator complete.");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT1, CheckPrSingleHopForIntKeysTask_REGION)
  {
    LOG("CheckPrSingleHopForIntKeysTask_REGION started.");
    int failureCount = 0;

    LOGDEBUG("CheckPrSingleHopForIntKeysTask_REGION create region  = %s ",
             partitionRegionName);
    auto dataReg = getHelper()->getRegion(partitionRegionName);

    for (int i = 0; i < 3000; i++) {
      auto keyPtr =
          std::dynamic_pointer_cast<CacheableKey>(CacheableInt32::create(i));

      try {
        LOGDEBUG("CPPTEST: Putting key %d with hashcode %d", i,
                 keyPtr->hashcode());
        dataReg->put(keyPtr, keyPtr->hashcode());
        bool networkhop = TestUtils::getCacheImpl(getHelper()->cachePtr)
                              ->getAndResetNetworkHopFlag();
        LOGDEBUG("CheckPrSingleHopForIntKeysTask_REGION: networkhop %d ",
                 networkhop);
        if (networkhop) {
          failureCount++;
        }
        int8_t serverGroupFlag = TestUtils::getCacheImpl(getHelper()->cachePtr)
                                     ->getAndResetServerGroupFlag();
        LOGDEBUG(
            "CheckPrSingleHopForIntKeysTask_REGION: serverGroupFlag is %d "
            "failureCount = %d",
            serverGroupFlag, failureCount);
        ASSERT(serverGroupFlag != 2,
               "serverGroupFlag should not be equal to 2");
      } catch (CacheServerException&) {
        LOGERROR("CPPTEST: Put caused extra hop.");
        FAIL("Put caused extra hop.");
      } catch (CacheWriterException&) {
        LOGERROR("CPPTEST: Put caused extra hop.");
        FAIL("Put caused extra hop.");
      } catch (Exception& ex) {
        LOGERROR("CPPTEST: Put caused unexpected %s: %s", ex.getName().c_str(),
                 ex.what());
        cleanProc();
        FAIL("Put caused unexpected exception");
      } catch (...) {
        LOGERROR("CPPTEST: Put caused random exception");
        cleanProc();
        FAIL("Put caused unexpected exception");
      }
    }
    ASSERT(failureCount < 70, "Count should be less than 70");
    LOG("CheckPrSingleHopForIntKeysTask_REGION put completed.");

    for (int i = 0; i < 1000; i++) {
      auto keyPtr =
          std::dynamic_pointer_cast<CacheableKey>(CacheableInt32::create(i));

      try {
        LOGDEBUG("CPPTEST: getting key %d with hashcode %d", i,
                 keyPtr->hashcode());
        dataReg->get(keyPtr);
        bool networkhop = TestUtils::getCacheImpl(getHelper()->cachePtr)
                              ->getAndResetNetworkHopFlag();
        LOGDEBUG("CheckPrSingleHopForIntKeysTask_REGION: networkhop %d ",
                 networkhop);
        ASSERT(!networkhop, "It is networkhop operation.");
        int8_t serverGroupFlag = TestUtils::getCacheImpl(getHelper()->cachePtr)
                                     ->getAndResetServerGroupFlag();
        LOGDEBUG(
            "CheckPrSingleHopForIntKeysTask_REGION: serverGroupFlag is %d ",
            serverGroupFlag);
        ASSERT(serverGroupFlag != 2,
               "serverGroupFlag should not be equal to 2");
      } catch (CacheServerException&) {
        LOGERROR("CPPTEST: get caused extra hop.");
        FAIL("get caused extra hop.");
      } catch (CacheWriterException&) {
        LOGERROR("CPPTEST: get caused extra hop.");
        FAIL("get caused extra hop.");
      } catch (Exception& ex) {
        LOGERROR("CPPTEST: get caused unexpected %s: %s", ex.getName().c_str(),
                 ex.what());
        cleanProc();
        FAIL("get caused unexpected exception");
      } catch (...) {
        LOGERROR("CPPTEST: get caused random exception");
        cleanProc();
        FAIL("get caused unexpected exception");
      }
    }
    LOG("CheckPrSingleHopForIntKeysTask_REGION get completed.");

    for (int i = 1000; i < 2000; i++) {
      std::vector<std::shared_ptr<CacheableKey>> keys;
      for (int j = i; j < i + 5; j++) {
        keys.push_back(CacheableInt32::create(j));
      }

      try {
        const auto values = dataReg->getAll(keys);
        bool networkhop = TestUtils::getCacheImpl(getHelper()->cachePtr)
                              ->getAndResetNetworkHopFlag();
        ASSERT(values.size() == 5, "number of value size should be 5");
        LOGDEBUG("CheckPrSingleHopForIntKeysTask_REGION: networkhop %d ",
                 networkhop);
        ASSERT(!networkhop, "It is networkhop operation.");
        int8_t serverGroupFlag = TestUtils::getCacheImpl(getHelper()->cachePtr)
                                     ->getAndResetServerGroupFlag();
        LOGDEBUG(
            "CheckPrSingleHopForIntKeysTask_REGION: serverGroupFlag is %d ",
            serverGroupFlag);
        ASSERT(serverGroupFlag != 2,
               "serverGroupFlag should not be equal to 2");
      } catch (CacheServerException&) {
        LOGERROR("CPPTEST: getAll caused extra hop.");
        FAIL("getAll caused extra hop.");
      } catch (CacheWriterException&) {
        LOGERROR("CPPTEST: getAll caused extra hop.");
        FAIL("getAll caused extra hop.");
      } catch (Exception& ex) {
        LOGERROR("CPPTEST: getALL caused unexpected %s: %s",
                 ex.getName().c_str(), ex.what());
        cleanProc();
        FAIL("getAll caused unexpected exception");
      } catch (...) {
        LOGERROR("CPPTEST: getAll caused random exception");
        cleanProc();
        FAIL("getAll caused unexpected exception");
      }

      try {
        const auto values = dataReg->getAll(keys, CacheableInt32::create(1000));
        bool networkhop = TestUtils::getCacheImpl(getHelper()->cachePtr)
                              ->getAndResetNetworkHopFlag();
        ASSERT(values.size() == 5, "number of value size should be 5");
        LOGDEBUG("CheckPrSingleHopForIntKeysTask_REGION: networkhop %d ",
                 networkhop);
        ASSERT(!networkhop, "It is networkhop operation.");
        int8_t serverGroupFlag = TestUtils::getCacheImpl(getHelper()->cachePtr)
                                     ->getAndResetServerGroupFlag();
        LOGDEBUG(
            "CheckPrSingleHopForIntKeysTask_REGION: serverGroupFlag is %d ",
            serverGroupFlag);
        ASSERT(serverGroupFlag != 2,
               "serverGroupFlag should not be equal to 2");
      } catch (CacheServerException&) {
        LOGERROR("CPPTEST: getAllwithCallBackArg caused extra hop.");
        FAIL("getAll caused extra hop.");
      } catch (CacheWriterException&) {
        LOGERROR("CPPTEST: getAll caused extra hop.");
        FAIL("getAll caused extra hop.");
      } catch (Exception& ex) {
        LOGERROR("CPPTEST: getALL caused unexpected %s: %s",
                 ex.getName().c_str(), ex.what());
        cleanProc();
        FAIL("getAll caused unexpected exception");
      } catch (...) {
        LOGERROR("CPPTEST: getAll caused random exception");
        cleanProc();
        FAIL("getAll caused unexpected exception");
      }
    }
    LOG("CheckPrSingleHopForIntKeysTask_REGION getAll completed.");

    for (int i = 0; i < 1000; i++) {
      auto keyPtr =
          std::dynamic_pointer_cast<CacheableKey>(CacheableInt32::create(i));

      try {
        LOGDEBUG("CPPTEST: destroying key %d with hashcode %d", i,
                 keyPtr->hashcode());
        dataReg->destroy(keyPtr);
        bool networkhop = TestUtils::getCacheImpl(getHelper()->cachePtr)
                              ->getAndResetNetworkHopFlag();
        LOGDEBUG("CheckPrSingleHopForIntKeysTask_REGION: networkhop %d ",
                 networkhop);
        ASSERT(!networkhop, "It is networkhop operation.");
        int8_t serverGroupFlag = TestUtils::getCacheImpl(getHelper()->cachePtr)
                                     ->getAndResetServerGroupFlag();
        LOGDEBUG(
            "CheckPrSingleHopForIntKeysTask_REGION: serverGroupFlag is %d ",
            serverGroupFlag);
        ASSERT(serverGroupFlag != 2,
               "serverGroupFlag should not be equal to 2");
      } catch (CacheServerException&) {
        LOGERROR("CPPTEST: destroy caused extra hop.");
        FAIL("destroy caused extra hop.");
      } catch (CacheWriterException&) {
        LOGERROR("CPPTEST: destroy caused extra hop.");
        FAIL("destroy caused extra hop.");
      } catch (Exception& ex) {
        LOGERROR("CPPTEST: destroy caused unexpected %s: %s",
                 ex.getName().c_str(), ex.what());
        cleanProc();
        FAIL("destroy caused unexpected exception");
      } catch (...) {
        LOGERROR("CPPTEST: destroy caused random exception");
        cleanProc();
        FAIL("destroy caused unexpected exception");
      }
    }
    LOG("CheckPrSingleHopForIntKeysTask_REGION destroy completed.");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT1, CloseCache1)
  { 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");
    }
  }
END_TASK_DEFINITION

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

DUNIT_TASK_DEFINITION(SERVER1, CreateLocator1)
  {
    // starting locator
    if (isLocator) CacheHelper::initLocator(1);
    LOG("Locator1 started");
  }
END_TASK_DEFINITION

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

DUNIT_TASK_DEFINITION(SERVER1, CreateServer1_With_Locator_PR)
  {
    // starting servers
    if (isLocalServer) {
      CacheHelper::initServer(1, "cacheserver1_fpr.xml", locatorsG);
    }
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(SERVER2, CreateServer2_With_Locator_PR)
  {
    // starting servers
    if (isLocalServer) {
      CacheHelper::initServer(2, "cacheserver2_fpr.xml", locatorsG);
    }
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(SERVER3, CreateServer3_With_Locator_PR)
  {
    // starting servers
    if (isLocalServer) {
      CacheHelper::initServer(3, "cacheserver3_fpr.xml", locatorsG);
    }
  }
END_TASK_DEFINITION

DUNIT_MAIN
  {
    CALL_TASK(CreateLocator1);

    CALL_TASK(CreateServer1_With_Locator_PR);
    CALL_TASK(CreateServer2_With_Locator_PR);
    CALL_TASK(CreateServer3_With_Locator_PR);

    CALL_TASK(StepOne_Pooled_Locator);

    CALL_TASK(SetRegion1);
    CALL_TASK(CheckPrSingleHopForIntKeysTask_REGION);

    CALL_TASK(SetRegion2);
    CALL_TASK(CheckPrSingleHopForIntKeysTask_REGION);

    CALL_TASK(SetRegion3);
    CALL_TASK(CheckPrSingleHopForIntKeysTask_REGION);

    CALL_TASK(CloseCache1);

    CALL_TASK(CloseServer1);
    CALL_TASK(CloseServer2);
    CALL_TASK(CloseServer3);

    CALL_TASK(CloseLocator1);
  }
END_MAIN
