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

/* This is to test
1) Client should connect to server that in the specified server group,even if
the same region exists in other servers.
2) Region operation should pass if there is atleast one server in the
server-group having the region.
3) 2nd case should be true if no server-group is specified .
*/

#define CLIENT1 s1p1
#define CLIENT2 s1p2
#define LOCATOR1 s2p1
#define SERVER s2p2

bool isLocalServer = false;
bool isLocator = false;

const std::string locHostPort =
    CacheHelper::getLocatorHostPort(isLocator, isLocalServer, 1);
const char *poolRegNames[] = {"PoolRegion1", "PoolRegion2", "PoolRegion3"};
const char *poolName = "__TEST_POOL1__";

const char *serverGroup = "ServerGroup1";

DUNIT_TASK_DEFINITION(LOCATOR1, StartLocator1)
  {
    // starting locator
    if (isLocator) CacheHelper::initLocator(1);
    LOG("Locator1 started");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(SERVER, StartServers)
  {
    if (isLocalServer) {
      CacheHelper::initServer(1, "cacheserver1_pool.xml", locHostPort);
    }
    if (isLocalServer) {
      CacheHelper::initServer(2, "cacheserver2_pool.xml", locHostPort);
    }
    if (isLocalServer) {
      CacheHelper::initServer(3, "cacheserver3_pool.xml", locHostPort);
    }
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT1, StartClient1)
  {
    initClient(true);
    // CLIENT1 create three regions
    getHelper()->createPool(poolName, locHostPort, serverGroup);

    getHelper()->createRegionAndAttachPool(poolRegNames[0], USE_ACK,
                                           "__TEST_POOL1__");
    getHelper()->createRegionAndAttachPool(poolRegNames[1], USE_ACK,
                                           "__TEST_POOL1__");
    getHelper()->createRegionAndAttachPool(poolRegNames[2], USE_ACK,
                                           "__TEST_POOL1__");

    LOG("Clnt1Init complete.");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT2, StartClient2)
  {
    initClient(true);
    // Create Pool with no server group
    getHelper()->createPool(poolName, locHostPort, {});

    getHelper()->createRegionAndAttachPool(poolRegNames[0], USE_ACK,
                                           "__TEST_POOL1__");
    getHelper()->createRegionAndAttachPool(poolRegNames[1], USE_ACK,
                                           "__TEST_POOL1__");
    getHelper()->createRegionAndAttachPool(poolRegNames[2], USE_ACK,
                                           "__TEST_POOL1__");

    LOG("Clnt2 Init complete.");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT1, CreateClient1Entries)
  {
    try {
      createEntry(poolRegNames[0], keys[0], vals[0]);
    } catch (...) {
      LOG("Operations on Region 1 should Pass.");
      throw;
    }

    try {
      createEntry(poolRegNames[1], keys[0], vals[0]);
      FAIL("Operations on R2 should throw RegionNotFoundException");
    } catch (const apache::geode::client::CacheServerException &) {
      LOG("Expected exception.");
    } catch (...) {
      LOG("Operation on Region 2 got unexpected exception.");
      throw;
    }
    LOG("CreateClient1Entries complete.");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT2, CreateClient2Entries)
  {
    // operations on R1/ R2 should pass and R3 should Fail.
    try {
      createEntry(poolRegNames[0], keys[0], vals[0]);
    } catch (...) {
      LOG("Operations on Region 1 should Pass.");
      throw;
    }

    try {
      createEntry(poolRegNames[2], keys[0], vals[0]);
      FAIL("Operations on R3 should throw RegionNotFoundException");
    } catch (const apache::geode::client::CacheServerException &) {
      LOG("Expected exception.");
    } catch (...) {
      LOG("Operation on Region 2 got unexpected exception.");
      throw;
    }
    LOG("CreateClient2Entries complete.");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT1, StopClient1)
  {
    cleanProc();
    LOG("Clnt1Down complete: Keepalive = True");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT2, StopClient2)
  {
    cleanProc();
    LOG("Clnt1Down complete: Keepalive = True");
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(SERVER, CloseServers)
  {
    // stop servers
    if (isLocalServer) {
      CacheHelper::closeServer(1);
      LOG("SERVER1 stopped");
    }
    if (isLocalServer) {
      CacheHelper::closeServer(2);
      LOG("SERVER2 stopped");
    }
    if (isLocalServer) {
      CacheHelper::closeServer(3);
      LOG("SERVER3 stopped");
    }
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(LOCATOR1, CloseLocator1)
  {
    // stop locator
    if (isLocator) {
      CacheHelper::closeLocator(1);
      LOG("Locator1 stopped");
    }
  }
END_TASK_DEFINITION

DUNIT_MAIN
  {
    CALL_TASK(StartLocator1);
    CALL_TASK(StartServers);
    CALL_TASK(StartClient1);
    CALL_TASK(StartClient2);
    CALL_TASK(CreateClient1Entries);
    CALL_TASK(CreateClient2Entries);
    CALL_TASK(StopClient1);
    CALL_TASK(StopClient2);
    CALL_TASK(CloseServers);
    CALL_TASK(CloseLocator1);
  }
END_MAIN
