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