/*
 * 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 "ThinClientHelper.hpp"
#include "testUtils.hpp"

/* This is to test
1) If Connections are left idle ,they timed out to min connections.
2) To validate PoolAttributes.
3) Create two pools with same name(in parallel threads).It should fail.
*/

#define CLIENT1 s1p1
#define CLIENT2 s1p2
#define LOCATOR1 s2p1
#define SERVER s2p2

bool isLocalServer = false;
bool isLocator = false;

const char* locHostPort =
    CacheHelper::getLocatorHostPort(isLocator, isLocalServer, 1);
const char* poolRegNames[] = {"PoolRegion1"};
const char* poolName = "__TEST_POOL1__";
const char* poolName1 = "clientPool";

const char* serverGroup = "ServerGroup1";
std::shared_ptr<Cache> cachePtr;

class putThread : public ACE_Task_Base {
 private:
  std::shared_ptr<Region> regPtr;

 public:
  explicit putThread(const char* name) : regPtr(getHelper()->getRegion(name)) {}

  int svc(void) {
    // TODO: No. of connection should be = minConnection

    for (int i = 0; i < 10000; i++) {
      try {
        regPtr->put(keys[i % 5], vals[i % 6]);
      } catch (const Exception&) {
        // ignore
      } catch (...) {
        // ignore
      }
      // TODO: Check no. of connection > minConnetion
    }
    // LOG(" Incremented 100 times by thread.");
    return 0;
  }
  void start() { activate(); }
  void stop() { wait(); }
};

void doAttrTestingAndCreatePool(const char* poolName) {
  auto poolFac = getHelper()->getCache()->getPoolManager().createFactory();
  poolFac.setFreeConnectionTimeout(std::chrono::milliseconds(10000));
  poolFac.setLoadConditioningInterval(std::chrono::milliseconds(60000));
  poolFac.setSocketBufferSize(1024);
  poolFac.setReadTimeout(std::chrono::milliseconds(10000));
  poolFac.setMinConnections(4);
  poolFac.setMaxConnections(8);
  poolFac.setIdleTimeout(std::chrono::seconds(5));
  poolFac.setRetryAttempts(5);
  poolFac.setPingInterval(std::chrono::milliseconds(120000));
  poolFac.setUpdateLocatorListInterval(std::chrono::milliseconds(122000));
  poolFac.setStatisticInterval(std::chrono::milliseconds(120000));
  poolFac.setServerGroup(serverGroup);
  poolFac.setSubscriptionEnabled(true);
  poolFac.setSubscriptionRedundancy(1);
  poolFac.setSubscriptionMessageTrackingTimeout(
      std::chrono::milliseconds(500000));
  poolFac.setSubscriptionAckInterval(std::chrono::milliseconds(120000));
  poolFac.addLocator("localhost", CacheHelper::staticLocatorHostPort1);
  // poolFacPtr->setMultiuserSecurityMode(true);
  poolFac.setPRSingleHopEnabled(false);

 auto pptr = poolFac.create(poolName);

 // Validate the attributes
 ASSERT(pptr->getFreeConnectionTimeout() == std::chrono::milliseconds(10000),
        "FreeConnectionTimeout Should have been 10000");
 ASSERT(pptr->getLoadConditioningInterval() == std::chrono::milliseconds(60000),
        "LoadConditioningInterval Should have been 60000");
 ASSERT(pptr->getSocketBufferSize() == 1024,
        "SocketBufferSize Should have been 1024");
 ASSERT(pptr->getReadTimeout() == std::chrono::milliseconds(10000),
        "ReadTimeout Should have been 10000");
 ASSERT(pptr->getMinConnections() == 4, "MinConnections Should have been 4");
 ASSERT(pptr->getMaxConnections() == 8, "MaxConnections Should have been 8");
 ASSERT(pptr->getIdleTimeout() == std::chrono::seconds(5),
        "IdleTimeout Should have been 5s");
 ASSERT(pptr->getRetryAttempts() == 5, "RetryAttempts Should have been 5");
 ASSERT(pptr->getPingInterval() == std::chrono::milliseconds(120000),
        "PingInterval Should have been 120000");
 ASSERT(
     pptr->getUpdateLocatorListInterval() == std::chrono::milliseconds(122000),
     "UpdateLocatorListInterval Should have been 122000");
 ASSERT(pptr->getStatisticInterval() == std::chrono::milliseconds(120000),
        "StatisticInterval Should have been 120000");
 ASSERT(pptr->getServerGroup() == "ServerGroup1",
        "ServerGroup Should have been ServerGroup1");
 ASSERT(pptr->getSubscriptionEnabled() == true,
        "SubscriptionEnabled Should have been true");
 ASSERT(pptr->getSubscriptionRedundancy() == 1,
        "SubscriptionRedundancy Should have been 1");
 ASSERT(pptr->getSubscriptionMessageTrackingTimeout() ==
            std::chrono::milliseconds(500000),
        "SubscriptionMessageTrackingTimeout Should have been 500000");
 ASSERT(pptr->getSubscriptionAckInterval() == std::chrono::milliseconds(120000),
        "SubscriptionAckInterval Should have been 120000");
 // ASSERT(pptr->getMultiuserSecurityMode()==true,"SetMultiuserSecurityMode
 // Should have been true");
 ASSERT(pptr->getPRSingleHopEnabled() == false,
        "PRSingleHopEnabled should have been false");
}

void doAttrTesting(const char* poolName1) {
  //auto poolFacPtr = cachePtr->getPoolFactory();
  auto pptr = getHelper()->getCache()->getPoolManager().find(poolName1);
  // auto pptr = poolFacPtr->find(poolName1);

  ASSERT(pptr->getName() == "clientPool",
         "Pool name should have been clientPool");
  ASSERT(pptr->getFreeConnectionTimeout() == std::chrono::milliseconds(10000),
         "FreeConnectionTimeout Should have been 10000");
  ASSERT(pptr->getLoadConditioningInterval() == std::chrono::seconds(1),
         "LoadConditioningInterval Should have been 1");
  ASSERT(pptr->getSocketBufferSize() == 1024,
         "SocketBufferSize Should have been 1024");
  ASSERT(pptr->getReadTimeout() == std::chrono::seconds(10),
         "ReadTimeout Should have been 10");
  ASSERT(pptr->getMinConnections() == 2, "MinConnections Should have been 2");
  ASSERT(pptr->getMaxConnections() == 5, "MaxConnections Should have been 5");
  ASSERT(pptr->getIdleTimeout() == std::chrono::milliseconds(5),
         "IdleTimeout Should have been 5ms");
  ASSERT(pptr->getRetryAttempts() == 5, "RetryAttempts Should have been 5");
  ASSERT(pptr->getPingInterval() == std::chrono::seconds(1),
         "PingInterval Should have been 1");
  ASSERT(
      pptr->getUpdateLocatorListInterval() == std::chrono::milliseconds(25000),
      "UpdateLocatorListInterval Should have been 25000");
  ASSERT(pptr->getStatisticInterval() == std::chrono::seconds(1),
         "StatisticInterval Should have been 1");
  ASSERT(pptr->getServerGroup() == "ServerGroup1",
         "ServerGroup Should have been ServerGroup1");
  ASSERT(pptr->getSubscriptionEnabled() == true,
         "SubscriptionEnabled Should have been true");
  ASSERT(pptr->getSubscriptionRedundancy() == 1,
         "SubscriptionRedundancy Should have been 1");
  ASSERT(
      pptr->getSubscriptionMessageTrackingTimeout() == std::chrono::seconds(5),
      "SubscriptionMessageTrackingTimeout Should have been 5");
  ASSERT(pptr->getSubscriptionAckInterval() == std::chrono::seconds(1),
         "SubscriptionAckInterval Should have been 1");
  ASSERT(pptr->getPRSingleHopEnabled() == false,
         "PRSingleHopEnabled should have been false");
}

DUNIT_TASK(LOCATOR1, StartLocator1)
  {
    // starting locator
    if (isLocator) CacheHelper::initLocator(1);
    LOG("Locator1 started");
  }
END_TASK(StartLocator1)

DUNIT_TASK(SERVER, StartS12)
  {
    if (isLocalServer) {
      CacheHelper::initServer(1, "cacheserver1_pool.xml", locHostPort);
    }
    if (isLocalServer) {
      CacheHelper::initServer(2, "cacheserver2_pool.xml", locHostPort);
    }
  }
END_TASK(StartS12)

DUNIT_TASK(CLIENT1, StartC1)
  {
   auto props = Properties::create();
   props->insert("redundancy-monitor-interval", "120s");
   props->insert("statistic-sampling-enabled", "false");
   props->insert("statistic-sample-rate", "120s");

   initClient(true, props);

   doAttrTestingAndCreatePool(poolName);

   // Do PoolCreation testing , create another pool with same name
   auto poolFac = getHelper()->getCache()->getPoolManager().createFactory();
   try {
     auto pptr = poolFac.create(poolName);
     FAIL("Pool creation with same name should fail");
   } catch (IllegalStateException&) {
     LOG("OK:Pool creation with same name should fail");
   } catch (...) {
     FAIL("Pool creation with same name should fail");
    }

    createRegionAndAttachPool(poolRegNames[0], USE_ACK, poolName);
    LOG("Clnt1Init complete.");
  }
END_TASK(StartC1)

DUNIT_TASK(CLIENT2, StartC2)
  {
   auto props = Properties::create();
   std::string path = "cacheserver_pool_client.xml";
   std::string duplicateFile;
   CacheHelper::createDuplicateXMLFile(duplicateFile, path);

   props->insert("cache-xml-file", duplicateFile.c_str());

   try {
     LOG(" starts client");
     initClient(true, props);
     LOG(" started client");
     ASSERT(getHelper()
                    ->getCache()
                    ->getPoolManager()
                    .find("clientPoolMultiUser")
                    ->getMultiuserAuthentication() == true,
            "MultiUser secure mode should be true for Pool");
   } catch (const Exception& excp) {
     LOG("Exception during client 2 XML creation");
     LOG(excp.what());
    }
    doAttrTesting(poolName1);
  }
END_TASK(StartC2)

// Test min-max connection.
DUNIT_TASK(CLIENT1, ClientOp)
  {
    // Wait for load conditioning thread to reduce pool connections to
    // min.
    SLEEP(5000);
    // Check current # connections they should be == min
    std::string poolName =
        getHelper()->getRegion(poolRegNames[0])->getAttributes().getPoolName();
    int level = TestUtils::getCacheImpl(getHelper()->cachePtr)
                    ->getPoolSize(poolName.c_str());
    int min = getHelper()
                  ->getCache()
                  ->getPoolManager()
                  .find(poolName.c_str())
                  ->getMinConnections();
    char logmsg[100] = {0};
    sprintf(logmsg, "Pool level not equal to min level. Expected %d, actual %d",
            min, level);
    ASSERT(level == min, logmsg);

    putThread* threads[25];
    for (int thdIdx = 0; thdIdx < 10; thdIdx++) {
      threads[thdIdx] = new putThread(poolRegNames[0]);
      threads[thdIdx]->start();
    }

    SLEEP(5000);  // wait for threads to become active

    // Check current # connections they should be == max
    level = TestUtils::getCacheImpl(getHelper()->cachePtr)
                ->getPoolSize(poolName.c_str());
    int max = getHelper()
                  ->getCache()
                  ->getPoolManager()
                  .find(poolName.c_str())
                  ->getMaxConnections();
    sprintf(logmsg, "Pool level not equal to max level. Expected %d, actual %d",
            max, level);
    ASSERT(level == max, logmsg);

    for (int thdIdx = 0; thdIdx < 10; thdIdx++) {
      threads[thdIdx]->stop();
    }

    // Milli second sleep: IdleTimeout is 5 sec, load conditioning
    // interval is 1 min
    LOG("Waiting 25 sec for idle timeout to kick in");
    SLEEP(25000);

    level = TestUtils::getCacheImpl(getHelper()->cachePtr)
                ->getPoolSize(poolName.c_str());
    min = getHelper()
              ->getCache()
              ->getPoolManager()
              .find(poolName.c_str())
              ->getMinConnections();
    sprintf(logmsg,
            "Pool level not equal to min level after idle timeout. "
            "Expected %d, actual %d",
            min, level);
    ASSERT(level == min, logmsg);

    LOG("Waiting 1 minute for load conditioning to kick in");
    SLEEP(60000);

    level = TestUtils::getCacheImpl(getHelper()->cachePtr)
                ->getPoolSize(poolName.c_str());
    sprintf(logmsg,
            "Pool level not equal to min level after load "
            "conditioning. Expected %d, actual %d",
            min, level);
    ASSERT(level == min, logmsg);
  }
END_TASK(ClientOp)

DUNIT_TASK(CLIENT1, StopC1)
  {
    cleanProc();
    LOG("Clnt1Down complete: Keepalive = True");
  }
END_TASK(StopC1)

DUNIT_TASK(CLIENT2, StopC2)
  {
    cleanProc();
    LOG("Clnt1Down complete: Keepalive = True");
  }
END_TASK(StopC2)

DUNIT_TASK(SERVER, CloseServers)
  {
    // stop servers
    if (isLocalServer) {
      CacheHelper::closeServer(1);
      LOG("SERVER1 stopped");
    }
    if (isLocalServer) {
      CacheHelper::closeServer(2);
      LOG("SERVER2 stopped");
    }
  }
END_TASK(CloseServers)

DUNIT_TASK(LOCATOR1, CloseLocator1)
  {
    // stop locator
    if (isLocator) {
      CacheHelper::closeLocator(1);
      LOG("Locator1 stopped");
    }
  }
END_TASK(CloseLocator1)
