/*=========================================================================
 * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
 * This product is protected by U.S. and international copyright
 * and intellectual property laws. Pivotal products are covered by
 * one or more patents listed at http://www.pivotal.io/patents.
 *=========================================================================
 */
#include "fw_dunit.hpp"
#include <gfcpp/GemfireCppCache.hpp>
#include <ace/High_Res_Timer.h>

#include <ace/OS.h>
#include <string>

#define ROOT_NAME "DistOps"
#define ROOT_SCOPE DISTRIBUTED_ACK

#include "CacheHelper.hpp"

using namespace gemfire;
using namespace test;

bool isLocalServer = false;
const char* endPoints = CacheHelper::getTcrEndpoints( isLocalServer, 3 );
CacheHelper* cacheHelper = NULL;
volatile int g_redundancyLevel = 0;

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

const char * endPoint = CacheHelper::getTcrEndpoints( isLocalServer, 1 );
static bool isLocator = false;
static int numberOfLocators = 1;
const char* locatorsG = CacheHelper::getLocatorHostPort( isLocator, numberOfLocators);
volatile bool g_poolConfig = false;
volatile bool g_poolLocators = false;
void initClient( int redundancyLevel )
{
  if ( cacheHelper == NULL ) {
    cacheHelper = new CacheHelper( endPoints, redundancyLevel );
  }
  g_redundancyLevel = redundancyLevel;
  ASSERT( cacheHelper, "Failed to create a CacheHelper client instance." );
}
void initClient()
{
  if( cacheHelper == NULL ) {
    cacheHelper = new CacheHelper( true );
  }
  ASSERT( cacheHelper, "Failed to create a CacheHelper client instance." );
}

void cleanProc()
{
  if ( cacheHelper != NULL ) {
    delete cacheHelper;
  cacheHelper = NULL;
  }
}

CacheHelper * getHelper()
{
  ASSERT( cacheHelper != NULL, "No cacheHelper initialized." );
  return cacheHelper;
}


void _verifyEntry( const char * name, const char * key, const char * val, bool noKey, bool isCreated = false )
{
  // Verify key and value exist in this region, in this process.
  const char * value = ( val == 0 ) ? "" : val;
  char * buf = (char *)malloc( 1024 + strlen( key ) + strlen( value ));
  ASSERT( buf, "Unable to malloc buffer for logging." );
  if ( !isCreated ) {
    if ( noKey )
      sprintf( buf, "Verify key %s does not exist in region %s", key, name );
    else if ( val == 0 )
      sprintf( buf, "Verify value for key %s does not exist in region %s", key, name );
    else
      sprintf( buf, "Verify value for key %s is: %s in region %s", key, value, name );
    LOG( buf );
  }
  free(buf);

  RegionPtr regPtr = getHelper()->getRegion( name );
  ASSERT( regPtr != NULLPTR, "Region not found." );

  CacheableKeyPtr keyPtr = createKey( key );

  // if the region is no ack, then we may need to wait...
  if ( !isCreated ) {
    if ( noKey == false ) { // need to find the key!
      ASSERT( regPtr->containsKey( keyPtr ), "Key not found in region." );
    }
    if ( val != NULL ) { // need to have a value!
      //ASSERT( regPtr->containsValueForKey( keyPtr ), "Value not found in region." );
    }
  }

  // loop up to MAX times, testing condition
  uint32_t MAX = 100;
  // ARB: changed sleep from 10 ms
  uint32_t SLEEP = 10; // milliseconds
  uint32_t containsKeyCnt = 0;
  uint32_t containsValueCnt = 0;
  uint32_t testValueCnt = 0;

  for ( int i = MAX; i >= 0; i-- ) {
    if ( isCreated ) {
      if ( !regPtr->containsKey( keyPtr ) )
        containsKeyCnt++;
      else
        break;
      ASSERT( containsKeyCnt < MAX, "Key has not been created in region." );
    }
    else {
      if ( noKey ) {
        if ( regPtr->containsKey( keyPtr ) )
          containsKeyCnt++;
        else
          break;
        ASSERT( containsKeyCnt < MAX, "Key found in region." );
      }
      if ( val == NULL ) {
        if ( regPtr->containsValueForKey( keyPtr ) )
          containsValueCnt++;
        else
          break;
        ASSERT( containsValueCnt < MAX, "Value found in region." );
      }

      if ( val != NULL ) {
        CacheableStringPtr checkPtr = dynCast<CacheableStringPtr>( regPtr->get( keyPtr ) );

        ASSERT( checkPtr != NULLPTR, "Value Ptr should not be null." );
        char buf[1024];
        sprintf( buf, "In verify loop, get returned %s for key %s", checkPtr->asChar(), key );
        LOG( buf );
        if ( strcmp( checkPtr->asChar(), value ) != 0 ){
          testValueCnt++;
        }else{
          break;
        }
        ASSERT( testValueCnt < MAX, "Incorrect value found." );
      }
    }
    dunit::sleep( SLEEP );
  }
}

#define verifyEntry( x, y, z ) _verifyEntry( x, y, z, __LINE__ )

void _verifyEntry( const char * name, const char * key, const char * val, int line )
{
  char logmsg[1024];
  sprintf( logmsg, "verifyEntry() called from %d.\n", line );
  LOG( logmsg );
  _verifyEntry( name, key, val, false );
  LOG( "Entry verified." );
}

#define verifyCreated( x, y ) _verifyCreated( x, y, __LINE__ )

void _verifyCreated( const char *name, const char *key, int line )
{
  char logmsg[1024];
  sprintf( logmsg, "verifyCreated() called from %d.\n", line );
  LOG( logmsg );
  _verifyEntry( name, key, NULL, false, true );
  LOG( "Entry created." );
}

void createRegion( const char* name, bool ackMode, bool clientNotificationEnabled = false )
{
  LOG( "createRegion() entered." );
  fprintf( stdout, "Creating region --  %s  ackMode is %d\n", name, ackMode );
  fflush( stdout );
  // ack, caching
  RegionPtr regPtr = getHelper()->createRegion( name, ackMode, true,
      NULLPTR, endPoints, clientNotificationEnabled );
  ASSERT( regPtr != NULLPTR, "Failed to create region." );
  LOG( "Region created." );
}

void createEntry( const char * name, const char * key, const char * value )
{
  LOG( "createEntry() entered." );
  fprintf( stdout, "Creating entry -- key: %s  value: %s in region %s\n", key, value, name );
  fflush( stdout );
  // Create entry, verify entry is correct
  CacheableKeyPtr keyPtr = createKey( key );
  CacheableStringPtr valPtr = CacheableString::create( value );

  RegionPtr regPtr = getHelper()->getRegion( name );
  ASSERT( regPtr != NULLPTR, "Region not found." );

  ASSERT( !regPtr->containsKey( keyPtr ), "Key should not have been found in region." );
  ASSERT( !regPtr->containsValueForKey( keyPtr ), "Value should not have been found in region." );

  //regPtr->create( keyPtr, valPtr );
  regPtr->put( keyPtr, valPtr );
  LOG( "Created entry." );

  verifyEntry( name, key, value );
  LOG( "Entry created." );
}

void updateEntry( const char * name, const char * key, const char * value )
{
  LOG( "updateEntry() entered." );
  fprintf( stdout, "Updating entry -- key: %s  value: %s in region %s\n", key, value, name );
  fflush( stdout );
  // Update entry, verify entry is correct
  CacheableKeyPtr keyPtr = createKey( key );
  CacheableStringPtr valPtr = CacheableString::create( value );

  RegionPtr regPtr = getHelper()->getRegion( name );
  ASSERT( regPtr != NULLPTR, "Region not found." );

  ASSERT( regPtr->containsKey( keyPtr ), "Key should have been found in region." );
  //ASSERT( regPtr->containsValueForKey( keyPtr ), "Value should have been found in region." );

  regPtr->put( keyPtr, valPtr );
  LOG( "Put entry." );

  verifyEntry( name, key, value );
  LOG( "Entry updated." );
}

void doNetsearch( const char * name, const char * key, const char * value )
{
  LOG( "doNetsearch() entered." );
  fprintf( stdout, "Netsearching for entry -- key: %s  expecting value: %s in region %s\n", key, value, name );
  fflush( stdout );
  // Get entry created in Process A, verify entry is correct
  CacheableKeyPtr keyPtr = CacheableKey::create( key );

  RegionPtr regPtr = getHelper()->getRegion( name );
  fprintf( stdout, "netsearch  region %s\n", regPtr->getName() );
  fflush( stdout );
  ASSERT( regPtr != NULLPTR, "Region not found." );

  //ASSERT( !regPtr->containsKey( keyPtr ), "Key should not have been found in region." );
  //ASSERT( !regPtr->containsValueForKey( keyPtr ), "Value should not have been found in region." );

  CacheableStringPtr checkPtr = dynCast<CacheableStringPtr>( regPtr->get( keyPtr ) ); // force a netsearch

  if ( checkPtr != NULLPTR ) {
    LOG( "checkPtr is not null" );
      char buf[1024];
      sprintf( buf, "In net search, get returned %s for key %s", checkPtr->asChar(), key );
      LOG( buf );
  }else{
    LOG( "checkPtr is NULL" );
  }
  verifyEntry( name, key, value );
  LOG( "Netsearch complete." );
}

const char * testregex[] = { "Key-*1", "Key-*2", "Key-*3", "Key-*4" };
const char * keys[] = { "Key-1", "Key-2", "Key-3", "Key-4" };
const char * vals[] = { "Value-1", "Value-2", "Value-3", "Value-4" };
const char * nvals[] = { "New Value-1", "New Value-2", "New Value-3", "New Value-4" };

const char * regionNames[] = { "DistRegionAck", "DistRegionNoAck" };

const bool USE_ACK = true;
const bool NO_ACK = false;
void initClientAndRegion( int redundancy, const char* endpointsList = endPoints)
{
  g_redundancyLevel = redundancy;
  PropertiesPtr pp  = Properties::create();
  if ( g_poolConfig ) {
    if (g_poolLocators) {
      getHelper()->createPoolWithLocators("__TESTPOOL1_", locatorsG, true, redundancy);
    }
    else {
      getHelper()->createPoolWithEPs("__TESTPOOL1_", endpointsList, true, redundancy);
    }
    getHelper()->createRegionAndAttachPool(regionNames[0], USE_ACK, "__TESTPOOL1_", true);
    getHelper()->createRegionAndAttachPool(regionNames[1], USE_ACK, "__TESTPOOL1_", true);
  }
  else {
    createRegion( regionNames[0], USE_ACK, false );
    createRegion( regionNames[1], NO_ACK, false );
  }
}
//#include "ThinClientDurableInit.hpp"
#include "LocatorHelper.hpp"
#include "ThinClientTasks_C2S2.hpp"
DUNIT_TASK_DEFINITION( SERVER1, CreateServer1 )
{
  if ( isLocalServer )
    CacheHelper::initServer( 1, "cacheserver_notify_subscription.xml" );
  LOG( "SERVER1 started" );
}
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION( CLIENT1, InitClient1_R1 )
{
  if( !g_poolConfig )
    initClient( 1 );
  else
    initClient( );
  LOG( "Initialized client with redundancy level 1." );
  initClientAndRegion( 1 );
}
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION( CLIENT2, InitClient2_R1 )
{
   if( !g_poolConfig )
     initClient( 1 );
   else
     initClient( );
   initClientAndRegion( 1 );
  LOG( "Initialized client with redundancy level 1." );
}
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION( CLIENT1, InitClient1_R3 )
{
  if( !g_poolConfig )
     initClient( 3 );
   else
     initClient( );
  initClientAndRegion( 3 );
  LOG( "Initialized client with redundancy level 3." );
}
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION( CLIENT2, InitClient2_R3 )
{
  if( !g_poolConfig )
    initClient( 3 );
  else
    initClient( );
  initClientAndRegion( 3 );
  LOG( "Initialized client with redundancy level 3." );
}
END_TASK_DEFINITION

/*DUNIT_TASK_DEFINITION( CLIENT1, StepOne )
{
  createRegion( regionNames[0], USE_ACK, false );
  createRegion( regionNames[1], NO_ACK, false );
  LOG( "StepOne complete." );
}
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION( CLIENT2, StepTwo )
{
  createRegion( regionNames[0], USE_ACK, false );
  createRegion( regionNames[1], NO_ACK, false );

  LOG( "StepTwo complete." );
}
END_TASK_DEFINITION
*/
DUNIT_TASK_DEFINITION( SERVER2, CreateServer2 )
{
  if ( isLocalServer )
    CacheHelper::initServer( 2, "cacheserver_notify_subscription2.xml" );
  LOG( "SERVER2 started" );
}
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION( CLIENT2, RegisterRegexes )
{
  RegionPtr regPtr0 = getHelper()->getRegion( regionNames[0] );
  RegionPtr regPtr1 = getHelper()->getRegion( regionNames[1] );

  if ( g_redundancyLevel > 1 ) {
      regPtr0->registerRegex( testregex[0] );
      regPtr1->registerRegex( testregex[2] );
  } else {
    regPtr0->registerRegex( testregex[0] );
    regPtr1->registerRegex( testregex[2] );
  }
}
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION( CLIENT1, StepThree )
{
  createEntry( regionNames[0], keys[0], vals[0] );
  createEntry( regionNames[0], keys[1], vals[1] );
  createEntry( regionNames[1], keys[2], vals[2] );
  createEntry( regionNames[1], keys[3], vals[3] );
  LOG( "StepThree complete." );
}
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION( CLIENT2, StepFour )
{
  verifyCreated( regionNames[0], keys[0] );
  verifyCreated( regionNames[1], keys[2] );
  verifyEntry( regionNames[0], keys[0], vals[0] );
  verifyEntry( regionNames[1], keys[2], vals[2] );
  doNetsearch( regionNames[0], keys[1], vals[1] );
  doNetsearch( regionNames[1], keys[3], vals[3] );
  LOG( "StepFour complete." );
}
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION( SERVER1, CloseServer1 )
{
  if ( isLocalServer ) {
    CacheHelper::closeServer( 1 );
    LOG( "SERVER1 stopped" );
  }
  SLEEP( 5000 );
}
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION( CLIENT1, StepFive )
{
  updateEntry( regionNames[0], keys[0], nvals[0] );
  updateEntry( regionNames[0], keys[1], nvals[1] );
  updateEntry( regionNames[1], keys[2], nvals[2] );
  updateEntry( regionNames[1], keys[3], nvals[3] );
  SLEEP( 1000 );
  LOG( "StepFive complete." );
}
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION( CLIENT2, StepSix )
{
  VectorOfCacheableKey vec0, vec1;
  RegionPtr reg0 = getHelper( )->getRegion( regionNames[0] );
  RegionPtr reg1 = getHelper( )->getRegion( regionNames[1] );
  reg0->serverKeys( vec0 );
  reg1->serverKeys( vec1 );
  ASSERT( vec0.size( ) == 2, "Should have 2 keys in first region." );
  ASSERT( vec1.size( ) == 2, "Should have 2 keys in second region." );
  std::string key0, key1;
  key0 = vec0[0]->toString( )->asChar( );
  key1 = vec0[1]->toString( )->asChar( );
  ASSERT( key0 != key1, "The two keys should be different in first region." );
  ASSERT( key0 == keys[0] || key0 == keys[1],
      "Unexpected key in first region." );
  ASSERT( key1 == keys[0] || key1 == keys[1],
      "Unexpected key in first region." );

  key0 = vec1[0]->toString( )->asChar( );
  key1 = vec1[1]->toString( )->asChar( );
  ASSERT( key0 != key1, "The two keys should be different in second region." );
  ASSERT( key0 == keys[2] || key0 == keys[3],
      "Unexpected key in second region." );
  ASSERT( key1 == keys[2] || key1 == keys[3],
      "Unexpected key in second region." );

  verifyEntry( regionNames[0], keys[0], nvals[0] );
  verifyEntry( regionNames[0], keys[1], vals[1] );
  verifyEntry( regionNames[1], keys[2], nvals[2] );
  verifyEntry( regionNames[1], keys[3], vals[3] );
  LOG( "StepSix complete." );
}
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION( SERVER1, CreateServer11 )
{
  if ( isLocalServer )
  {
    if ( g_poolConfig && g_poolLocators ) {
    CacheHelper::initServer( 1, "cacheserver_notify_subscription.xml", locatorsG );
    }
    else{
      CacheHelper::initServer( 1, "cacheserver_notify_subscription.xml" );
    }
  LOG( "SERVER1 started" );
  }
  SLEEP(5000);
}
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION( SERVER2, CloseServer2 )
{
  if ( isLocalServer ) {
    CacheHelper::closeServer( 2 );
    LOG( "SERVER2 stopped" );
  }
  SLEEP( 5000 );
}
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION( SERVER1, CreateServer3 )
{
  if ( isLocalServer ){
    if ( g_poolConfig && g_poolLocators ){
      CacheHelper::initServer( 3, "cacheserver_notify_subscription3.xml", locatorsG );
    }
    else{
    CacheHelper::initServer( 3, "cacheserver_notify_subscription3.xml" );
    }
  }
  LOG( "SERVER3 started" );
  SLEEP( 15000 );
}
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION( CLIENT1, StepSeven )
{
  updateEntry( regionNames[0], keys[0], vals[0] );
  updateEntry( regionNames[0], keys[1], vals[1] );
  updateEntry( regionNames[1], keys[2], vals[2] );
  updateEntry( regionNames[1], keys[3], vals[3] );
  SLEEP( 1000 );
  LOG( "StepSeven complete." );
}
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION( CLIENT2, StepEight )
{
  verifyEntry( regionNames[0], keys[0], vals[0] );
  verifyEntry( regionNames[0], keys[1], vals[1] );
  verifyEntry( regionNames[1], keys[2], vals[2] );
  verifyEntry( regionNames[1], keys[3], vals[3] );

  RegionPtr regPtr1 = getHelper()->getRegion( regionNames[1] );
  regPtr1->unregisterRegex( testregex[2] );

  LOG( "StepEight complete." );
}
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION( SERVER2, CreateServer21 )
{
  if ( isLocalServer ){
    if( g_poolConfig && g_poolLocators){
      CacheHelper::initServer( 2, "cacheserver_notify_subscription2.xml", locatorsG );
    }
    else{
      CacheHelper::initServer( 2, "cacheserver_notify_subscription2.xml" );
    }
  }
  LOG( "SERVER2 started" );
  SLEEP( 15000 );
}
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION( SERVER1, CloseServer3 )
{
  if ( isLocalServer ) {
    CacheHelper::closeServer( 3 );
    LOG( "SERVER3 stopped" );
  }
  SLEEP( 15000 );
}
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION( CLIENT1, StepNine )
{
  updateEntry( regionNames[0], keys[0], nvals[0] );
  updateEntry( regionNames[0], keys[1], nvals[1] );
  updateEntry( regionNames[1], keys[2], nvals[2] );
  updateEntry( regionNames[1], keys[3], nvals[3] );
  SLEEP( 1000 );
  LOG( "StepNine complete." );
}
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION( CLIENT2, StepTen )
{
  verifyEntry( regionNames[0], keys[0], nvals[0] );
  verifyEntry( regionNames[0], keys[1], vals[1] );
  verifyEntry( regionNames[1], keys[2], vals[2] );
  verifyEntry( regionNames[1], keys[3], vals[3] );
  LOG( "StepTen complete." );
}
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION( SERVER1, CloseServer11 )
{
  if ( isLocalServer ) {
    CacheHelper::closeServer( 1 );
    LOG( "SERVER1 stopped" );
  }
  SLEEP( 15000 );
}
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION( CLIENT1, StepEleven )
{
  updateEntry( regionNames[0], keys[0], vals[0] );
  updateEntry( regionNames[0], keys[1], vals[1] );
  updateEntry( regionNames[1], keys[2], vals[2] );
  updateEntry( regionNames[1], keys[3], vals[3] );
  SLEEP( 1000 );
  LOG( "StepEleven complete." );
}
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION( CLIENT2, StepTwelve )
{
  verifyEntry( regionNames[0], keys[0], vals[0] );
  verifyEntry( regionNames[0], keys[1], vals[1] );
  verifyEntry( regionNames[1], keys[2], vals[2] );
  verifyEntry( regionNames[1], keys[3], vals[3] );
  LOG( "StepTwelve complete." );
}
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, CloseServer21 )
{
  if ( isLocalServer ) {
    CacheHelper::closeServer( 2 );
    LOG( "SERVER2 stopped" );
  }
  SLEEP( 5000 );
}
END_TASK_DEFINITION

void runRegexFailOver(bool poolConfig = true, bool poolLocators = true)
{
  initLocatorSettings( poolConfig, poolLocators );
  for ( int runNum = 1; runNum <= 2; runNum++ ) {
    if( poolConfig && poolLocators )
    {
      CALL_TASK( CreateLocator1 );
      CALL_TASK( CreateServer1_With_Locator_XML );
    }
    else
    {
      CALL_TASK( CreateServer1 );
    }
    if ( runNum == 1 ) {
      CALL_TASK( InitClient1_R1 );
      CALL_TASK( InitClient2_R1 );
    } else {
      CALL_TASK( InitClient1_R3 );
      CALL_TASK( InitClient2_R3 );
    }
   // CALL_TASK( StepOne );
   // CALL_TASK( StepTwo );
    if( poolConfig && poolLocators )
    {
      CALL_TASK( CreateServer2_With_Locator_XML ); ///included from LocatorHelper.hpp
    }
    else
    {
      CALL_TASK( CreateServer2 );
    }
    CALL_TASK( RegisterRegexes );
    CALL_TASK( StepThree );
    CALL_TASK( StepFour );
    CALL_TASK( CloseServer1 );
    CALL_TASK( StepFive );
    CALL_TASK( StepSix );
    CALL_TASK( CreateServer11 );
    CALL_TASK( CloseServer2 );
    CALL_TASK( CreateServer3 );
    CALL_TASK( StepSeven );
    CALL_TASK( StepEight );
    CALL_TASK( CreateServer21 );
    CALL_TASK( CloseServer3 );
    CALL_TASK( StepNine );
    CALL_TASK( StepTen );
    CALL_TASK( CloseServer11 );
    CALL_TASK( StepEleven );
    CALL_TASK( StepTwelve );
    CALL_TASK( CloseCache1 );
    CALL_TASK( CloseCache2 );
    CALL_TASK( CloseServer21 );
    if( poolConfig && poolLocators)
      CALL_TASK( CloseLocator1 );
    SLEEP(1000);
  }
}

DUNIT_MAIN
{
  runRegexFailOver(false);
  runRegexFailOver(true, true);
  runRegexFailOver(true, false);
}
END_MAIN
