/*
 * 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 <gfcpp/statistics/StatisticsFactory.hpp>

#include <ace/ACE.h>
#include <ace/Guard_T.h>
#include <ace/Thread_Mutex.h>
#include <ace/OS.h>
#include <ace/OS_NS_time.h>
#include <ace/OS_NS_sys_time.h>
#include <ace/OS_NS_unistd.h>
#include <ace/OS_NS_Thread.h>
#include <ace/Dirent.h>
#include <ace/Dirent_Selector.h>
#include <ace/OS_NS_sys_stat.h>

/* This is to test Statistics Functionality, Following Parameters are considered
1-  Creation of Stats Type / Statistics / Statistics Descriptors ( int_t/ Long /
Double ,  Counter / Gauge ) .
2- Use Functions Get/ Set / Inc in normal / abnormal way.  and check consistency
in single / multithreaded env.
*/

#define CLIENT1 s1p1
#define CLIENT2 s1p2
#define SERVER1 s2p1
#define CLIENT3 s2p2
const char* g_ClientName;
const char* MyClients[] = {"MyClientA", "MyClientB", "MyClientC"};
int LogFileSettings[] = {1, 2, 100};
int MyResults[] = {1 * 1024 * 1024, 2 * 1024 * 1024, 5 * 1024 * 1024};
int NumberOfFiles[] = {10, 2, 1};
int DiskFileSettings[] = {10, 3, 5};

#define EPSILON 0.0000001

#include "locator_globals.hpp"
#include "LocatorHelper.hpp"

bool IsDoubleEqual(double d1, double d2) {
  double diff = d1 > d2 ? (d1 - d2) : (d2 - d1);
  return (diff < EPSILON) ? true : false;
}

struct TestStatisticsType {
  StatisticsType* testStatsType;
  int statIdIntCounter;
  int statIdIntGauge;
  int statIdLongCounter;
  int statIdLongGauge;
  int statIdDoubleCounter;
  int statIdDoubleGauge;
};

class IncThread : public ACE_Task_Base {
 private:
  Statistics* m_stat;
  TestStatisticsType* m_type;

 public:
  IncThread(Statistics* stat, TestStatisticsType* type)
      : m_stat(stat), m_type(type) {}

  int svc(void) {
    /* Just 1000 Inc, Stop after that  */
    for (int incIdx = 0; incIdx < 1000; incIdx++) {
      m_stat->incInt(m_type->statIdIntCounter, 1);
      m_stat->incInt(m_type->statIdIntGauge, 1);
      m_stat->incLong(m_type->statIdLongCounter, 1);
      m_stat->incLong(m_type->statIdLongGauge, 1);
      m_stat->incDouble(m_type->statIdDoubleCounter, 1.0);
      m_stat->incDouble(m_type->statIdDoubleGauge, 1.0);
    }
    // LOG(" Incremented 1000 times by thread.");
    return 0;
  }
  void start() { activate(); }
  void stop() { wait(); }
};

static int comparator(const dirent** d1, const dirent** d2) {
  if (strlen((*d1)->d_name) < strlen((*d2)->d_name)) {
    return -1;
  } else if (strlen((*d1)->d_name) > strlen((*d2)->d_name)) {
    return 1;
  }

  int diff = ACE_OS::strcmp((*d1)->d_name, (*d2)->d_name);
  if (diff < 0) {
    return -1;
  } else if (diff > 0) {
    return 1;
  } else {
    return 0;
  }
}

static int selector(const dirent* d) {
  std::string inputname(d->d_name);
  LOGINFO("selector %s\t g_ClientName = %s", inputname.c_str(), g_ClientName);
  return ACE_OS::strstr(d->d_name, g_ClientName) != 0;
}

/* Common Functions */
void initClientWithStats() {
  PropertiesPtr pp = Properties::create();
  pp->insert("statistic-sampling-enabled", "true");
  pp->insert("statistic-sample-rate", 1);
  pp->insert("statistic-archive-file", "./statArchive.gfs");
  pp->insert("notify-ack-interval", 1);

  initClientWithPool(true, "__TEST_POOL1__", locatorsG, "ServerGroup1", pp, 0,
                     true);
  getHelper()->createPooledRegion(regionNames[0], USE_ACK, locatorsG,
                                  "__TEST_POOL1__", true, true);
}

void initClientWithStatsDisabled() {
  PropertiesPtr pp = Properties::create();
  pp->insert("statistic-sampling-enabled", "false");
  // pp->insert("statistic-sample-rate", 1);
  // pp->insert("statistic-archive-file", "./statArchive.gfs");

  initClientWithPool(true, "__TEST_POOL1__", locatorsG, "ServerGroup1", pp, 0,
                     true);
  getHelper()->createPooledRegion(regionNames[0], USE_ACK, locatorsG,
                                  "__TEST_POOL1__", true, true);
}

void DoRegionOpsAndVerify() {
  RegionPtr regPtr0 = getHelper()->getRegion(regionNames[0]);

  for (int index = 0; index < 5; index++) {
    char key[100] = {0};
    char value[100] = {0};
    ACE_OS::sprintf(key, "Key-%d", index);
    ACE_OS::sprintf(value, "Value-%d", index);
    CacheableKeyPtr keyptr = CacheableKey::create(key);
    CacheablePtr valuePtr = CacheableString::create(value);
    regPtr0->put(keyptr, valuePtr);
  }

  CacheableKeyPtr keyptr = CacheableKey::create("Key-0");

  RegionEntryPtr regEntry = regPtr0->getEntry(keyptr);

  LOGINFO("regEntry->isDestroyed() = %d ", regEntry->isDestroyed());
  ASSERT(
      regEntry->isDestroyed() == false,
      "regionEntry is not destroyed, regEntry->isDestroyed must return false");

  bool flag ATTR_UNUSED = regPtr0->remove(keyptr);

  RegionEntryPtr remRegEntry = regPtr0->getEntry(keyptr);
  ASSERT(remRegEntry == NULLPTR,
         "regionEntry pointer to removed entry must be NULLPTR");

  if (remRegEntry != NULLPTR) {
    LOGINFO("remRegEntry->isDestroyed() = %d ", remRegEntry->isDestroyed());
    ASSERT(remRegEntry->isDestroyed() == true,
           "regionEntry is not destroyed, remRegEntry->isDestroyed must return "
           "false");
  } else {
    LOGINFO("regionEntry pointer for removed key is NULL");
  }

  CacheStatisticsPtr cacheStatptr(new CacheStatistics());
  // CacheStatisticsPtr cacheStatptr;
  try {
    CachePtr cache = dynCast<CachePtr>(
        regPtr0->getRegionService());  // This depends on LocalCache
                                       // implementing RegionService...
    bool flag = cache->getDistributedSystem()
                    ->getSystemProperties()
                    ->statisticsEnabled();
    LOGINFO("statisticsEnabled = %d ", flag);
    regEntry->getStatistics(cacheStatptr);
  } catch (StatisticsDisabledException& ex) {
    LOGINFO("Exception Caught:: StatisticsDisabledException");
  } catch (GeodeConfigException& e) {
    LOGINFO("Exception Caught:: %s", e.getMessage());
  } catch (Exception& ex) {
    LOGINFO("Exception Caught:: %s", ex.getMessage());
  }
  if (cacheStatptr != NULLPTR) {
    LOGINFO("LastAccessedTime = %d ", cacheStatptr->getLastAccessedTime());
  } else {
    LOGINFO("cacheStatptr is NULL");
  }
}

void initClientWithStatsAndLog(const char* str, int fileLimit, int diskLimit) {
  PropertiesPtr pp = Properties::create();
  pp->insert("log-file", str);
  pp->insert("log-level", "fine");
  pp->insert("log-file-size-limit", fileLimit);
  pp->insert("log-disk-space-limit", diskLimit);
  initClient(true, pp);
}

void createType(StatisticsFactory* statFactory, TestStatisticsType& testType) {
  StatisticDescriptor** statDescriptorArr = new StatisticDescriptor*[6];
  statDescriptorArr[0] = statFactory->createIntCounter(
      "IntCounter", "Test Statistic Descriptor int_t Counter.", "TestUnit");

  statDescriptorArr[1] = statFactory->createIntGauge(
      "IntGauge", "Test Statistic Descriptor int_t Gauge.", "TestUnit");

  statDescriptorArr[2] = statFactory->createLongCounter(
      "LongCounter", "Test Statistic Descriptor Long Counter.", "TestUnit");

  statDescriptorArr[3] = statFactory->createLongGauge(
      "LongGauge", "Test Statistic Descriptor Long Gauge.", "TestUnit");

  statDescriptorArr[4] = statFactory->createDoubleCounter(
      "DoubleCounter", "Test Statistic Descriptor Double Counter.", "TestUnit");

  statDescriptorArr[5] = statFactory->createDoubleGauge(
      "DoubleGauge", "Test Statistic Descriptor Double Gauge.", "TestUnit");

  StatisticsType* statsType = statFactory->createType(
      "TestStatsType", "Statistics for Unit Test.", statDescriptorArr, 6);

  ASSERT(statsType != NULL, "Error in creating Stats Type");

  testType.testStatsType = statsType;
  testType.statIdIntCounter = statsType->nameToId("IntCounter");
  testType.statIdIntGauge = statsType->nameToId("IntGauge");
  testType.statIdLongCounter = statsType->nameToId("LongCounter");
  testType.statIdLongGauge = statsType->nameToId("LongGauge");
  testType.statIdDoubleCounter = statsType->nameToId("DoubleCounter");
  testType.statIdDoubleGauge = statsType->nameToId("DoubleGauge");

  /* Test Find */
  ASSERT(statsType == statFactory->findType("TestStatsType"),
         " Find Type Failed");
}

void testGetSetIncFunctions(Statistics* stat, TestStatisticsType& type) {
  /* Set a initial value =  10 */
  stat->setInt(type.statIdIntCounter, 10);
  stat->setInt(type.statIdIntGauge, 10);
  stat->setLong(type.statIdLongCounter, 10);
  stat->setLong(type.statIdLongGauge, 10);
  stat->setDouble(type.statIdDoubleCounter, 10.0);
  stat->setDouble(type.statIdDoubleGauge, 10.0);
  LOG(" Setting Initial Value Complete");

  /* Check Initial Value = 10*/
  ASSERT(10 == stat->getInt(type.statIdIntCounter), " Check1 1 Failed ");
  ASSERT(10 == stat->getInt(type.statIdIntGauge), " Check1 2 Failed ");
  ASSERT(10 == stat->getLong(type.statIdLongCounter), " Check1 3 Failed ");
  ASSERT(10 == stat->getLong(type.statIdLongGauge), " Check1 4 Failed ");
  ASSERT(IsDoubleEqual(10.0, stat->getDouble(type.statIdDoubleCounter)),
         " Check1 5 Failed ");
  ASSERT(IsDoubleEqual(10.0, stat->getDouble(type.statIdDoubleGauge)),
         " Check1 6 Failed ");
  LOG(" All Set() were correct.");

  /* Increment single thread for 100 times */
  for (int incIdx = 0; incIdx < 100; incIdx++) {
    stat->incInt(type.statIdIntCounter, 1);
    stat->incInt(type.statIdIntGauge, 1);
    stat->incLong(type.statIdLongCounter, 1);
    stat->incLong(type.statIdLongGauge, 1);
    stat->incDouble(type.statIdDoubleCounter, 1.0);
    stat->incDouble(type.statIdDoubleGauge, 1.0);
    SLEEP(10);
  }
  LOG(" Incremented 100 times by 1.");

  /* Check Incremented Value = 110 */
  ASSERT(110 == stat->getInt(type.statIdIntCounter), " Check2 1 Failed ");
  ASSERT(110 == stat->getInt(type.statIdIntGauge), " Check2 2 Failed ");
  ASSERT(110 == stat->getLong(type.statIdLongCounter), " Check2 3 Failed ");
  ASSERT(110 == stat->getLong(type.statIdLongGauge), " Check2 4 Failed ");
  ASSERT(IsDoubleEqual(110.0, stat->getDouble(type.statIdDoubleCounter)),
         " Check2 5 Failed ");
  ASSERT(IsDoubleEqual(110.0, stat->getDouble(type.statIdDoubleGauge)),
         " Check2 6 Failed ");
  LOG(" Single thread Inc() Passed.");

  /* Increment parallelly  = 10,000 times */
  IncThread* threads[10];
  for (int thdIdx = 0; thdIdx < 10; thdIdx++) {
    threads[thdIdx] = new IncThread(stat, &type);
    threads[thdIdx]->start();
  }
  SLEEP(1000);
  for (int thdIdx = 0; thdIdx < 10; thdIdx++) {
    threads[thdIdx]->stop();
  }

  /* Check Final Value = 10,110 */
  ASSERT(10110 == stat->getInt(type.statIdIntCounter), " Check2 1 Failed ");
  ASSERT(10110 == stat->getInt(type.statIdIntGauge), " Check2 2 Failed ");
  ASSERT(10110 == stat->getLong(type.statIdLongCounter), " Check2 3 Failed ");
  ASSERT(10110 == stat->getLong(type.statIdLongGauge), " Check2 4 Failed ");
  ASSERT(IsDoubleEqual(10110.0, stat->getDouble(type.statIdDoubleCounter)),
         " Check2 5 Failed ");
  ASSERT(IsDoubleEqual(10110.0, stat->getDouble(type.statIdDoubleGauge)),
         " Check2 6 Failed ");
  LOG(" Parallel Inc() Passed.");
}

void statisticsTest() {
  /* Create Statistics in right and wrong manner */
  StatisticsFactory* factory = StatisticsFactory::getExistingInstance();

  /* Register a type */
  TestStatisticsType testType;
  createType(factory, testType);
  LOG("Statistics Type TestStats Registered");

  /* Create a statistics */
  Statistics* testStat1 =
      factory->createStatistics(testType.testStatsType, "TestStatistics");
  ASSERT(testStat1 != NULL, "Test Statistics Creation Failed");

  /* Tests Find Type , Find Statistics */
  Statistics* temp = factory->findFirstStatisticsByType(testType.testStatsType);
  ASSERT(temp == testStat1, "findFirstStatisticsByType Failed");
  LOG("Statistics testStat1 Created Successfully.");

  /* Test Set Functions */
  testGetSetIncFunctions(testStat1, testType);
  LOG("Get / Set / Inc Functions Tested ");

  /* Close Statistics */
  testStat1->close();
  Statistics* temp2 =
      factory->findFirstStatisticsByType(testType.testStatsType);
  ASSERT(temp2 == NULL, "Statistics close() Failed");

  LOG("StatisticsTest Completed");
}

void LogTest(int expectedResult, int noofFiles, int diskLimit) {
  unsigned int seed = 2;
  int rand1 = ACE_OS::rand_r(&seed) % 2;
  unsigned int seed2 = 700;
  int rand2 = ACE_OS::rand_r(&seed2) % 700;

  int rand = (rand1 + 8) * 1024 + rand2;
  LOGFINE(" random is %d", rand);
  char buf[10 * 1024];
  for (int i = 0; i < rand - 1; i++) {
    buf[i] = 'A';
  }
  buf[10 * 1024 - 1] = '\0';
  for (int j = 0; j < 2 * 1024; j++) {
    LOGFINE("%s", buf);
  }
  std::string dirname = ACE::dirname(".");
  struct dirent** resultArray;
  LOGFINE("dirname is %s ", dirname.c_str());
  int entries_count =
      ACE_OS::scandir(dirname.c_str(), &resultArray, selector, comparator);
  LOGFINE("entries_count is %d ", entries_count);
  ASSERT(entries_count == noofFiles,
         "files count should be equal to noofFiles");
  ACE_stat statBuf;
  int64_t spaceUsed = 0;
  char fullpath[512] = {0};
  for (int i = 0; i < entries_count; i++) {
    sprintf(fullpath, "%s%c%s", dirname.c_str(), ACE_DIRECTORY_SEPARATOR_CHAR,
            resultArray[i]->d_name);
    LOGFINE("fullpath is %s ", fullpath);
    ACE_OS::stat(fullpath, &statBuf);
    int64_t size = statBuf.st_size;
    ASSERT(size <= expectedResult,
           "individual file size should be less than equal to expectedResult");
    spaceUsed += size;
  }
  LOGFINE("spaceUsed is %d ", spaceUsed);
  ASSERT(spaceUsed <= 1024 * 1024 * diskLimit,
         "collective file size should be less than equal to diskLimit");
  LOG("LogTest Completed");
}

void StatFileTest() {
  LOG(" Starting Stat.gfs file test");
  /* Get Pid , Get File name : HARD Coding for File name pattern */
  char buff[1024];
  int32 pid = ACE_OS::getpid();
  ACE_OS::sprintf(buff, "./statArchive-%d.gfs", pid);
  std::string statFilename(buff);

  /* Test if this file Stat-pid.gfs is there */
  FILE* fp = fopen(statFilename.c_str(), "r");
  ASSERT(fp != NULL, "Statistics GFS file does not exist");
  if (fp != NULL) {
    LOG("SUCCESS: .gfs file exist.");
    fclose(fp);
  }

  LOG(" StatFileTest complete.");
}

/* Test Tasks */
DUNIT_TASK_DEFINITION(SERVER1, StartFirstServer)
  {
    if (isLocalServer) {
      CacheHelper::initServer(1, "cacheserver_notify_subscription.xml",
                              locatorsG);
    }
    LOG("SERVER started");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT1, ClientFirstInit)
  {
    initClientWithStats();
    LOG("Client Init complete.");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT1, StatTest)
  { statisticsTest(); }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT1, CloseFirstClient)
  {
    cleanProc();
    LOG("CLIENT closed");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT1, GFSFileTest)
  { StatFileTest(); }
END_TASK_DEFINITION

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

DUNIT_TASK_DEFINITION(SERVER1, StartSecondServer)
  {
    if (isLocalServer) {
      CacheHelper::initServer(1, "cacheserver_notify_subscription.xml",
                              locatorsG);
    }
    LOG("SERVER started");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT1, ClientSecondInit)
  {
    g_ClientName = MyClients[0];
    initClientWithStatsAndLog(MyClients[0], LogFileSettings[0],
                              DiskFileSettings[0]);
    LogTest(MyResults[0], NumberOfFiles[0], DiskFileSettings[0]);
    cleanProc();
    g_ClientName = MyClients[1];
    initClientWithStatsAndLog(MyClients[1], LogFileSettings[1],
                              DiskFileSettings[1]);
    LogTest(MyResults[1], NumberOfFiles[1], DiskFileSettings[1]);
    cleanProc();
    g_ClientName = MyClients[2];
    initClientWithStatsAndLog(MyClients[2], LogFileSettings[2],
                              DiskFileSettings[2]);
    LogTest(MyResults[2], NumberOfFiles[2], DiskFileSettings[2]);
    cleanProc();
  }
END_TASK_DEFINITION

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

// ADDED FOR TEST-COVERAGE
DUNIT_TASK_DEFINITION(SERVER1, StartThirdServer)
  {
    if (isLocalServer) {
      CacheHelper::initServer(1, "cacheserver_notify_subscription.xml",
                              locatorsG);
    }
    LOG("SERVER started");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT1, ClientThirdInit)
  {
    initClientWithStatsDisabled();
    LOG("Client Init complete.");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT1, RegionOps)
  { DoRegionOpsAndVerify(); }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT1, CloseThirdClient)
  {
    cleanProc();
    LOG("CLIENT closed");
  }
END_TASK_DEFINITION

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

DUNIT_MAIN
  {
    CALL_TASK(CreateLocator1)

    CALL_TASK(StartFirstServer)
    CALL_TASK(ClientFirstInit)
    CALL_TASK(StatTest)
    CALL_TASK(CloseFirstClient)
    CALL_TASK(GFSFileTest)
    CALL_TASK(CloseFirstServer)
    CALL_TASK(StartSecondServer)
    CALL_TASK(ClientSecondInit)
    CALL_TASK(CloseSecondServer)
    CALL_TASK(StartThirdServer)
    CALL_TASK(ClientThirdInit)
    CALL_TASK(RegionOps)
    CALL_TASK(CloseThirdClient)
    CALL_TASK(CloseThirdServer)

    CALL_TASK(CloseLocator1)
  }
END_MAIN
