/*
 * 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 <ace/High_Res_Timer.h>

#include <string>

#define ROOT_NAME "testThinClientMultiDS"
#define ROOT_SCOPE DISTRIBUTED_ACK

#include "ThinClientSecurityHelper.hpp"

#ifdef __disabled_test__

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

static int clientWithNothing = 0;
void initClient() {
  if (cacheHelper == nullptr) {
    auto config = Properties::create();
    if (clientWithNothing > 1) config->insert("grid-client", "true");
    clientWithNothing += 1;
    cacheHelper = new CacheHelper(true, config);
  }
  ASSERT(cacheHelper, "Failed to create a CacheHelper client instance.");
}

void initializeClient() {
  initCredentialGenerator();
  initClientAuth('A');
  LOG("client initialized.");
}
void startServer(int instance, const char *xmlfile, const char *lochostport) {
  credentialGeneratorHandler = CredentialGenerator::create("DUMMY");
  std::string cmdServerAuthenticator;
  cmdServerAuthenticator = credentialGeneratorHandler->getServerCmdParams(
      "authenticator:dummy", getXmlPath());
  printf("string %s", cmdServerAuthenticator.c_str());
  CacheHelper::initServer(instance, xmlfile, lochostport,
                          const_cast<char *>(cmdServerAuthenticator.c_str()),
                          false, true, true);
  LOG("Server started");
}

DUNIT_TASK_DEFINITION(SERVER1, CreateServer1)
  {
    CacheHelper::initServer(1, "cacheserver_notify_subscription.xml", nullptr,
                            nullptr, false, true, true);
    CacheHelper::initServer(2, "cacheserver_notify_subscription2.xml", nullptr,
                            nullptr, false, true, true);
    LOG("SERVER1 and server2 started");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(SERVER2, CreateServer2)
  {
    CacheHelper::initServer(3, "cacheserver_notify_subscription3.xml", nullptr,
                            nullptr, false, true, true);
    CacheHelper::initServer(4, "cacheserver_notify_subscription4.xml", nullptr,
                            nullptr, false, true, true);
    LOG("SERVER2 started");
  }
END_TASK_DEFINITION
DUNIT_TASK_DEFINITION(CLIENT1, InitClient1_Pool)
  {
    try {
      initClient();
    } catch (Exception &excp) {
      LOG(excp.what());
    }
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT2, InitClient2_Pool)
  {
    try {
      initClient();
    } catch (Exception &excp) {
      LOG(excp.what());
    }
  }
END_TASK_DEFINITION
DUNIT_TASK_DEFINITION(CLIENT1, StepOne_Pool_EndPoint)
  {
    try {
      // getHelper()->createPoolWithEPs("__TESTPOOL1_",
      // "localhost:24680,localhost:24681");
      // getHelper()->createPoolWithEPs("__TESTPOOL2_",
      // "localhost:24682,localhost:24683");
      char tmp[128];
      sprintf(tmp, "localhost:%d,localhost:%d", CacheHelper::staticHostPort1,
              CacheHelper::staticHostPort2);
      getHelper()->createPoolWithEPs("__TESTPOOL1_", tmp);
      char tmp2[128];
      sprintf(tmp2, "localhost:%d,localhost:%d", CacheHelper::staticHostPort3,
              CacheHelper::staticHostPort4);
      getHelper()->createPoolWithEPs("__TESTPOOL2_", tmp2);

      getHelper()->createRegionAndAttachPool(regionNames[0], USE_ACK,
                                             "__TESTPOOL1_", false);
      getHelper()->createRegionAndAttachPool(regionNames[1], NO_ACK,
                                             "__TESTPOOL2_", false);
      auto regPtr0 = getHelper()->getRegion(regionNames[0]);
      auto regPtr1 = getHelper()->getRegion(regionNames[1]);
      for (int i = 0; i < 100; i++) {
        regPtr0->put(keys[0], vals[0]);
        regPtr1->put(keys[2], vals[2]);
      }
    } catch (Exception &excp) {
      LOG(excp.what());
      ASSERT(false, "Got unexpected exception");
    }
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT2, StepTwo_Pool_EndPoint)
  {
    try {
      // getHelper()->createPoolWithEPs("__TESTPOOL1_",
      // "localhost:24680,localhost:24681",false);
      // getHelper()->createPoolWithEPs("__TESTPOOL2_",
      // "localhost:24682,localhost:24683",false);
      char tmp[128];
      sprintf(tmp, "localhost:%d,localhost:%d", CacheHelper::staticHostPort1,
              CacheHelper::staticHostPort2);
      getHelper()->createPoolWithEPs("__TESTPOOL1_", tmp);
      char tmp2[128];
      sprintf(tmp2, "localhost:%d,localhost:%d", CacheHelper::staticHostPort3,
              CacheHelper::staticHostPort4);
      getHelper()->createPoolWithEPs("__TESTPOOL2_", tmp2);

      getHelper()->createRegionAndAttachPool(regionNames[0], USE_ACK,
                                             "__TESTPOOL1_", false);
      getHelper()->createRegionAndAttachPool(regionNames[1], NO_ACK,
                                             "__TESTPOOL2_", false);
      auto regPtr0 = getHelper()->getRegion(regionNames[0]);
      auto regPtr1 = getHelper()->getRegion(regionNames[1]);
      for (int i = 0; i < 100; i++) {
        regPtr0->put(keys[1], vals[1]);
        regPtr1->put(keys[3], vals[3]);
      }
    } catch (Exception &excp) {
      LOG(excp.what());
      ASSERT(false, "Got unexpected exception");
    }

    LOG("Steptwo complete.");
  }
END_TASK_DEFINITION
DUNIT_TASK_DEFINITION(CLIENT1, StepOne_1)
  {
    try {
      auto regPtr0 = getHelper()->getRegion(regionNames[0]);
      auto regPtr1 = getHelper()->getRegion(regionNames[1]);
      auto checkPtr =
          std::dynamic_pointer_cast<CacheableString>(regPtr0->get(keys[2]));
      ASSERT(checkPtr == nullptr, "checkPtr should be null");
      auto checkPtr1 =
          std::dynamic_pointer_cast<CacheableString>(regPtr0->get(keys[0]));
      ASSERT(checkPtr1 != nullptr, "checkPtr1 should not be null");
    } catch (Exception &excp) {
      LOG(excp.what());
      ASSERT(false, "Got unexpected exception");
    }
  }
END_TASK_DEFINITION
DUNIT_TASK_DEFINITION(SERVER1, CloseServer1)
  {
    CacheHelper::closeServer(1);
    LOG("SERVER1 stopped");
  }
END_TASK_DEFINITION
DUNIT_TASK_DEFINITION(CLIENT1, StepOne_2)
  {
    try {
      auto regPtr0 = getHelper()->getRegion(regionNames[0]);
      auto regPtr1 = getHelper()->getRegion(regionNames[1]);
      for (int i = 0; i < 100; i++) {
        regPtr0->put(keys[0], regPtr1->get(keys[2]));
        regPtr1->put(keys[2], regPtr0->get(keys[0]));
      }

    } catch (Exception &excp) {
      LOG(excp.what());
      ASSERT(false, "Got unexpected exception");
    }
  }
END_TASK_DEFINITION
DUNIT_TASK_DEFINITION(CLIENT1, CloseCache1)
  { cleanProc(); }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT2, CloseCache2)
  { cleanProc(); }
END_TASK_DEFINITION
DUNIT_TASK_DEFINITION(SERVER2, CloseServer1_1)
  {
    CacheHelper::closeServer(2);
    LOG("SERVER2 stopped");
  }
END_TASK_DEFINITION
DUNIT_TASK_DEFINITION(SERVER2, CloseServer2)
  {
    CacheHelper::closeServer(3);
    CacheHelper::closeServer(4);
    LOG("SERVER2 stopped");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(SERVER1, SecureStartServer1)
  {
    char tmp[128];
    sprintf(tmp, "localhost:%d", CacheHelper::staticLocatorHostPort1);
    startServer(1, "cacheserver_notify_subscription.xml", tmp);
    startServer(2, "cacheserver_notify_subscription2.xml", tmp);
    LOG("SecureServer1 started");
  }
END_TASK_DEFINITION
DUNIT_TASK_DEFINITION(SERVER2, SecureStartServer2)
  {
    char tmp[128];
    sprintf(tmp, "localhost:%d", CacheHelper::staticLocatorHostPort2);
    startServer(3, "cacheserver_notify_subscription3.xml", tmp);
    startServer(4, "cacheserver_notify_subscription4.xml", tmp);
    LOG("SecureServer2 started");
  }
END_TASK_DEFINITION
DUNIT_TASK_DEFINITION(SERVER1, StartLocator1)
  {
    CacheHelper::initLocator(1, false, true);
    LOG("Locator1 started");
  }
END_TASK_DEFINITION
DUNIT_TASK_DEFINITION(SERVER2, StartLocator2)
  {
    CacheHelper::initLocator(2, false, true);
    LOG("Locator2 started");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT1, StartSecureClient1)
  {
    initializeClient();
    LOG("StartSecureClient1 started");
  }
END_TASK_DEFINITION
DUNIT_TASK_DEFINITION(CLIENT2, StartSecureClient2)
  {
    initializeClient();
    LOG("StartSecureClient2 started");
  }
END_TASK_DEFINITION
DUNIT_TASK_DEFINITION(CLIENT1, StepOne_Pool_SecureEndPoint)
  {
    try {
      //  getHelper()->createPoolWithEPs("__TESTPOOL1_",
      //  "localhost:24680,localhost:24681");
      // getHelper()->createPoolWithEPs("__TESTPOOL2_",
      // "localhost:24682,localhost:24683");
      char tmp[128];
      sprintf(tmp, "localhost:%d,localhost:%d", CacheHelper::staticHostPort1,
              CacheHelper::staticHostPort2);
      getHelper()->createPoolWithEPs("__TESTPOOL1_", tmp);
      char tmp2[128];
      sprintf(tmp2, "localhost:%d,localhost:%d", CacheHelper::staticHostPort3,
              CacheHelper::staticHostPort4);
      getHelper()->createPoolWithEPs("__TESTPOOL2_", tmp2);

      getHelper()->createRegionAndAttachPool(regionNames[0], USE_ACK,
                                             "__TESTPOOL1_", false);
      getHelper()->createRegionAndAttachPool(regionNames[1], NO_ACK,
                                             "__TESTPOOL2_", false);
      auto regPtr0 = getHelper()->getRegion(regionNames[0]);
      auto regPtr1 = getHelper()->getRegion(regionNames[1]);
      for (int i = 0; i < 100; i++) {
        regPtr0->put(keys[0], vals[0]);
        regPtr1->put(keys[2], vals[2]);
      }
    } catch (Exception &excp) {
      LOG(excp.what());
      ASSERT(false, "Got unexpected exception");
    }
    LOG("StepOne_Pool_SecureEndPoint complete.");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT2, StepTwo_Pool_SecureEndPoint)
  {
    try {
      // getHelper()->createPoolWithEPs("__TESTPOOL1_",
      // "localhost:24680,localhost:24681");
      // getHelper()->createPoolWithEPs("__TESTPOOL2_",
      // "localhost:24682,localhost:24683");
      char tmp[128];
      sprintf(tmp, "localhost:%d,localhost:%d", CacheHelper::staticHostPort1,
              CacheHelper::staticHostPort2);
      getHelper()->createPoolWithEPs("__TESTPOOL1_", tmp);
      char tmp2[128];
      sprintf(tmp2, "localhost:%d,localhost:%d", CacheHelper::staticHostPort3,
              CacheHelper::staticHostPort4);
      getHelper()->createPoolWithEPs("__TESTPOOL2_", tmp2);

      getHelper()->createRegionAndAttachPool(regionNames[0], USE_ACK,
                                             "__TESTPOOL1_", false);
      getHelper()->createRegionAndAttachPool(regionNames[1], NO_ACK,
                                             "__TESTPOOL2_", false);
      auto regPtr0 = getHelper()->getRegion(regionNames[0]);
      auto regPtr1 = getHelper()->getRegion(regionNames[1]);
      for (int i = 0; i < 100; i++) {
        regPtr0->put(keys[1], vals[1]);
        regPtr1->put(keys[3], vals[3]);
      }
    } catch (Exception &excp) {
      LOG(excp.what());
      ASSERT(false, "Got unexpected exception");
    }

    LOG("StepTwo_Pool_SecureEndPoint complete.");
  }
END_TASK_DEFINITION
DUNIT_TASK_DEFINITION(CLIENT1, StepOne_secureclient1)
  {
    try {
      auto regPtr0 = getHelper()->getRegion(regionNames[0]);
      auto regPtr1 = getHelper()->getRegion(regionNames[1]);
      auto checkPtr =
          std::dynamic_pointer_cast<CacheableString>(regPtr0->get(keys[2]));
      ASSERT(checkPtr == nullptr, "checkPtr should be null");
      auto checkPtr1 =
          std::dynamic_pointer_cast<CacheableString>(regPtr0->get(keys[0]));
      ASSERT(checkPtr1 != nullptr, "checkPtr1 should not be null");
    } catch (Exception &excp) {
      LOG(excp.what());
      ASSERT(false, "Got unexpected exception");
    }
    LOG("StepOne_secureclient1 complete.");
  }
END_TASK_DEFINITION
DUNIT_TASK_DEFINITION(CLIENT1, StepOne_secureclient2)
  {
    try {
      auto regPtr0 = getHelper()->getRegion(regionNames[0]);
      auto regPtr1 = getHelper()->getRegion(regionNames[1]);
      for (int i = 0; i < 100; i++) {
        regPtr0->put(keys[0], regPtr1->get(keys[2]));
        regPtr1->put(keys[2], regPtr0->get(keys[0]));
      }

    } catch (Exception &excp) {
      LOG(excp.what());
      ASSERT(false, "Got unexpected exception");
    }
    LOG("StepOne_secureclient2 complete.");
  }
END_TASK_DEFINITION
DUNIT_TASK_DEFINITION(SERVER1, CloseLocator1)
  {
    SLEEP(2000);
    CacheHelper::closeServer(2);
    CacheHelper::closeLocator(1);
    LOG("SERVER1 stopped");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(SERVER2, CloseLocator2)
  {
    CacheHelper::closeServer(3);
    CacheHelper::closeServer(4);
    CacheHelper::closeLocator(2);
    LOG("Locator1 stopped");
  }
END_TASK_DEFINITION
DUNIT_MAIN
  {
    CALL_TASK(CreateServer1);
    CALL_TASK(CreateServer2);
    CALL_TASK(InitClient1_Pool);
    CALL_TASK(InitClient2_Pool);
    CALL_TASK(StepOne_Pool_EndPoint);
    CALL_TASK(StepTwo_Pool_EndPoint);
    CALL_TASK(StepOne_1);
    CALL_TASK(CloseServer1);
    CALL_TASK(StepOne_2);
    CALL_TASK(CloseServer1_1);
    CALL_TASK(CloseServer2);
    CALL_TASK(CloseCache1);
    CALL_TASK(CloseCache2);
    // Test MultiDS with security config
    CALL_TASK(StartLocator1);
    CALL_TASK(StartLocator2);
    CALL_TASK(SecureStartServer1);
    CALL_TASK(SecureStartServer2);
    CALL_TASK(StartSecureClient1);
    CALL_TASK(StartSecureClient2);
    CALL_TASK(StepOne_Pool_SecureEndPoint);
    CALL_TASK(StepTwo_Pool_SecureEndPoint);
    CALL_TASK(StepOne_secureclient1);
    CALL_TASK(CloseServer1);
    CALL_TASK(StepOne_secureclient2);
    CALL_TASK(CloseCache1);
    CALL_TASK(CloseCache2);
    CALL_TASK(CloseLocator1);
    CALL_TASK(CloseLocator2);
  }
END_MAIN
#endif
