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

using apache::geode::client::Exception;
using apache::geode::client::IllegalStateException;

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);
    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);
    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);
    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);
    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)
