/*
 * 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, false, true, true);
    CacheHelper::initServer(2, "cacheserver_notify_subscription2.xml", {},
                            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, false, true, true);
    CacheHelper::initServer(4, "cacheserver_notify_subscription4.xml", {},
                            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
