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

#define ROOT_NAME "testEntriesMap"

#include "fw_helper.hpp"

#ifdef WIN32

BEGIN_TEST(NotOnWindows)
  { LOG("Too many non-external symbols used too fix right now on windows."); }
END_TEST(NotOnWindows)

#else

//#define BUILD_CPPCACHE 1
#include <gfcpp/GeodeCppCache.hpp>
#include <LRUEntriesMap.hpp>
#include <LRUMapEntry.hpp>
#include <VersionTag.hpp>
#include <stdlib.h>

using namespace apache::geode::client;
using namespace std;

typedef std::vector<MapEntryImplPtr> VectorOfMapEntry;

CacheableStringPtr createCacheable(const char* value) {
  CacheableStringPtr result = CacheableString::create(value);
  ASSERT(result != NULLPTR, "expected result non-NULL");
  return result;
}

BEGIN_TEST(PutAndGet)
  {
    CacheableStringPtr ccstr = createCacheable("100");
    CacheablePtr ct = ccstr;
    EntryFactory* entryFactory = EntryFactory::singleton;
    EntriesMap* entries = new ConcurrentEntriesMap(entryFactory, false);
    entries->open();
    CacheableKeyPtr keyPtr = CacheableKey::create((char*)"foobar");
    ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
    MapEntryImplPtr me;
    VersionTagPtr versionTag;
    CacheablePtr oldValue;
    entries->put(keyPtr, ct, me, oldValue, -1, 0, versionTag);
    CacheablePtr myValuePtr;
    entries->get(keyPtr, myValuePtr, me);
    ASSERT(myValuePtr != NULLPTR, "expected non-NULL");
    CacheableStringPtr strValue = dynCast<CacheableStringPtr>(myValuePtr);
    ASSERT(ccstr->operator==(*strValue), "expected 100");
    delete entries;
  }
END_TEST(PutAndGet)

BEGIN_TEST(CheckMapEntryImplPtr)
  {
    char error[1000] ATTR_UNUSED;
    MapEntryImplPtr mePtr;
    ASSERT(mePtr == NULLPTR, "expected mePtr to be NULL");
    CacheableKeyPtr keyPtr = CacheableKey::create(fwtest_Name);
    ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
    EntryFactory::singleton->newMapEntry(keyPtr, mePtr);
    ASSERT(mePtr != NULLPTR, "expected to not be null.");
  }
END_TEST(CheckMapEntryImplPtr)

BEGIN_TEST(RemoveTest)
  {
    CacheableStringPtr cst = createCacheable("200");
    CacheablePtr ct = cst;
    EntryFactory* entryFactory = EntryFactory::singleton;
    EntriesMap* entries = new ConcurrentEntriesMap(entryFactory, false);
    entries->open();
    CacheableKeyPtr keyPtr = CacheableKey::create(fwtest_Name);
    MapEntryImplPtr me;
    ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
    CacheablePtr oldValue;
    VersionTagPtr versionTag;
    entries->put(keyPtr, ct, me, oldValue, -1, 0, versionTag);
    CacheablePtr myValuePtr;
    (void)entries->remove(keyPtr, myValuePtr, me, -1, versionTag, false);
    CacheableStringPtr resPtr = dynCast<CacheableStringPtr>(myValuePtr);
    ASSERT(myValuePtr != NULLPTR, "expected to not be null.");
    ASSERT(resPtr->operator==(*createCacheable("200")),
           "CustomerType with m_foobar 200.");
    (void)entries->remove(keyPtr, myValuePtr, me, -1, versionTag, false);
    ASSERT(myValuePtr == NULLPTR,
           "expected already removed, and null result should clear ptr.");
  }
END_TEST(RemoveTest)

BEGIN_TEST(GetEntryTest)
  {
    CacheableStringPtr cst = createCacheable("200");
    CacheablePtr ct = cst;
    EntryFactory* entryFactory = EntryFactory::singleton;
    EntriesMap* entries = new ConcurrentEntriesMap(entryFactory, false);
    entries->open();
    CacheableKeyPtr keyPtr;
    MapEntryImplPtr me;
    keyPtr = CacheableKey::create(fwtest_Name);
    ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
    CacheablePtr oldValue;
    VersionTagPtr versionTag;
    entries->put(keyPtr, ct, me, oldValue, -1, 0, versionTag);
    MapEntryImplPtr mePtr;
    CacheablePtr ctPtr;
    entries->getEntry(keyPtr, mePtr, ctPtr);
    ASSERT(mePtr != NULLPTR, "should not be null.");
    CacheableStringPtr valPtr = dynCast<CacheableStringPtr>(ctPtr);
    ASSERT(valPtr->operator==(*cst),
           "Entry should have a CustomerType Value of 200");
    CacheableKeyPtr keyPtr1;
    mePtr->getKey(keyPtr1);
    ASSERT(keyPtr1->operator==(*keyPtr), "should have same key.");
  }
END_TEST(GetEntryTest)

BEGIN_TEST(MapEntryImplPtrRCTest)
  {
    // Test Reference Counting and destruction for MapEntry.
    CacheableKeyPtr keyPtr = CacheableKey::create("foobar");
    ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
    MapEntryImplPtr mePtr;
    EntryFactory ef;
    ef.newMapEntry(keyPtr, mePtr);
    CacheablePtr ct = createCacheable("someval");
    mePtr->setValue(ct);
  }
END_TEST(MapEntryImplPtrRCTest)

BEGIN_TEST(VectorOfMapEntryTestA)
  {
    VectorOfMapEntry* meVec = new VectorOfMapEntry();
    delete meVec;
  }
END_TEST(VectorOfMapEntryTestA)

BEGIN_TEST(VectorOfMapEntryTestB)
  {
    VectorOfMapEntry* meVec = new VectorOfMapEntry();
    meVec->resize(100);
    meVec->clear();
    meVec->resize(10);
    MapEntryImplPtr mePtr;
    for (int i = 0; i < 10; i++) {
      meVec->push_back(mePtr);
    }
    for (int j = 0; j < 10; j++) {
      meVec->pop_back();
    }
    delete meVec;
  }
END_TEST(VectorOfMapEntryTestB)

BEGIN_TEST(EntriesTest)
  {
    EntryFactory* entryFactory = EntryFactory::singleton;
    EntriesMap* entries = new ConcurrentEntriesMap(entryFactory, false);
    entries->open();
    char keyBuf[100];
    char valBuf[100];
    VersionTagPtr versionTag;
    MapEntryImplPtr me;
    for (int i = 0; i < 10; i++) {
      sprintf(keyBuf, "key_%d", i);
      sprintf(valBuf, "%d", i);
      CacheableKeyPtr keyPtr = CacheableKey::create(keyBuf);
      ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
      CacheablePtr v = createCacheable(valBuf);
      CacheablePtr oldValue;
      entries->put(keyPtr, v, me, oldValue, -1, 0, versionTag);
    }
    VectorOfRegionEntry* entriesVec = new VectorOfRegionEntry();
    entriesVec->resize(1);
    entries->entries(*entriesVec);
    // should be 10, but they are hashed so, we don't know what order they will
    // come in...
    int total = 0;
    int expectedTotal = 0;
    for (int k = 0; k < 10; k++) {
      expectedTotal += k;
      RegionEntryPtr rePtr = entriesVec->back();
      CacheableStringPtr ctPtr;
      CacheablePtr ccPtr;
      ccPtr = rePtr->getValue();
      ctPtr = dynCast<CacheableStringPtr>(ccPtr);
      test::cout << "value is " << ctPtr->asChar() << test::endl;
      int val = atoi(ctPtr->asChar());
      test::cout << "atoi returned " << val << test::endl;
      total += val;
      entriesVec->pop_back();
    }
    entriesVec->clear();
    entriesVec->resize(0);
    delete entriesVec;
    sprintf(keyBuf, "total = %d, expected = %d", total, expectedTotal);
    ASSERT(total == expectedTotal, keyBuf);
    delete entries;
  }
END_TEST(EntriesTest)

BEGIN_TEST(ValuesTest)
  {
    EntryFactory* entryFactory = EntryFactory::singleton;
    EntriesMap* entries = new ConcurrentEntriesMap(entryFactory, false);
    entries->open();
    char keyBuf[100];
    char valBuf[100];
    VersionTagPtr versionTag;
    MapEntryImplPtr me;
    for (int i = 0; i < 10; i++) {
      sprintf(keyBuf, "key_%d", i);
      sprintf(valBuf, "%d", i);
      CacheableKeyPtr keyPtr = CacheableKey::create(keyBuf);
      ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
      CacheablePtr v = createCacheable(valBuf);
      CacheablePtr oldValue;
      entries->put(keyPtr, v, me, oldValue, -1, 0, versionTag);
    }
    VectorOfCacheable* valuesVec = new VectorOfCacheable();
    valuesVec->resize(1);
    entries->values(*valuesVec);
    // should be 10, but they are hashed so, we don't know what order they will
    // come in...
    int total = 0;
    int expectedTotal = 0;
    for (int k = 0; k < 10; k++) {
      expectedTotal += k;
      CacheableStringPtr valuePtr =
          dynCast<CacheableStringPtr>(valuesVec->back());
      total += atoi(valuePtr->asChar());
      valuesVec->pop_back();
    }
    delete valuesVec;
    sprintf(keyBuf, "total = %d, expected = %d", total, expectedTotal);
    ASSERT(total == expectedTotal, keyBuf);
    delete entries;
  }
END_TEST(ValuesTest)

BEGIN_TEST(KeysTest)
  {
    EntryFactory* entryFactory = EntryFactory::singleton;
    EntriesMap* entries = new ConcurrentEntriesMap(entryFactory, false);
    entries->open();
    char keyBuf[100];
    char valBuf[100];
    VersionTagPtr versionTag;
    MapEntryImplPtr me;
    for (int i = 0; i < 10; i++) {
      sprintf(keyBuf, "key_%d", i);
      sprintf(valBuf, "%d", i);
      CacheableKeyPtr keyPtr = CacheableKey::create(keyBuf);
      ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
      CacheablePtr v = createCacheable(valBuf);
      CacheablePtr oldValue;
      entries->put(keyPtr, v, me, oldValue, -1, 0, versionTag);
    }
    VectorOfCacheableKey keysVec;
    // keysVec.resize( 1 );
    entries->keys(keysVec);
    // should be 10, but they are hashed so, we don't know what order they will
    // come in...
    int total = 0;
    int expectedTotal = 0;
    for (int k = 0; k < 10; k++) {
      expectedTotal += k;
      CacheableKeyPtr keyPtr = keysVec.back();
      CacheablePtr cvPtr;
      entries->get(keyPtr, cvPtr, me);
      CacheableStringPtr valuePtr = dynCast<CacheableStringPtr>(cvPtr);
      total += atoi(valuePtr->asChar());
      keysVec.pop_back();
    }
    sprintf(keyBuf, "total = %d, expected = %d", total, expectedTotal);
    ASSERT(total == expectedTotal, keyBuf);
    delete entries;
  }
END_TEST(KeysTest)

BEGIN_TEST(TestRehash)
  {
    EntryFactory* entryFactory = EntryFactory::singleton;
    ConcurrentEntriesMap* entries =
        new ConcurrentEntriesMap(entryFactory, false, NULL, 1);
    entries->open(10);
    ASSERT(entries->totalSegmentRehashes() == 0,
           "should not have rehashed yet.");
    char keyBuf[100];
    char valBuf[100];
    MapEntryImplPtr me;

    for (uint32_t i = 0; i < 10000; i++) {
      sprintf(keyBuf, "key_%d", i);
      sprintf(valBuf, "%d", i);
      CacheableKeyPtr keyPtr = CacheableKey::create(keyBuf);
      ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
      CacheablePtr v = createCacheable(valBuf);
      CacheablePtr oldValue;
      VersionTagPtr versionTag;
      entries->put(keyPtr, v, me, oldValue, -1, 0, versionTag);
    }
    // check rehash count...
    ASSERT(entries->totalSegmentRehashes() > 0,
           "should have rehashed several times.");
    // VectorOfMapEntry result ;
    // entries->entries( result );
    //  printf("entries->size()=%d\n", entries->size());
    ASSERT(entries->size() == 10000, "should be 10k items");
    for (uint32_t j = 0; j < 10000; j++) {
      sprintf(keyBuf, "key_%d", j);
      CacheableStringPtr valuePtr;
      CacheableKeyPtr keyPtr = CacheableKey::create(keyBuf);
      ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
      CacheablePtr cvPtr;
      entries->get(keyPtr, cvPtr, me);
      valuePtr = dynCast<CacheableStringPtr>(cvPtr);
      if (valuePtr == NULLPTR) {
        test::cout << "error finding key: " << keyBuf << test::endl;
        FAIL("should have found value for all keys after rehash.");
      }
    }
  }
END_TEST(TestRehash)

//---- LRU variants

BEGIN_TEST(LRUPutAndGet)
  {
    CacheableStringPtr cst = createCacheable("100");
    CacheablePtr ct = cst;
    MapEntryImplPtr me;
    EntryFactory* entryFactory = LRUEntryFactory::singleton;
    EntriesMap* entries = new LRUEntriesMap(
        entryFactory, NULL, LRUAction::LOCAL_DESTROY, 20, false);
    entries->open();
    ASSERT(entries->size() == 0, "expected size 0.");
    CacheableKeyPtr keyPtr = CacheableKey::create("foobar");
    CacheablePtr oldValue;
    VersionTagPtr versionTag;
    entries->put(keyPtr, ct, me, oldValue, -1, 0, versionTag);
    ASSERT(entries->size() == 1, "expected size 1.");
    CacheableStringPtr myValuePtr;
    CacheablePtr cvPtr;
    ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
    entries->get(keyPtr, cvPtr, me);
    myValuePtr = dynCast<CacheableStringPtr>(cvPtr);
    ASSERT(myValuePtr != NULLPTR, "expected non-NULL");
    ASSERT(cst->operator==(*myValuePtr), "expected 100");
    delete entries;
  }
END_TEST(LRUPutAndGet)

BEGIN_TEST(CheckLRUMapEntryImplPtr)
  {
    char error[1000] ATTR_UNUSED;
    MapEntryImplPtr mePtr;
    ASSERT(mePtr == NULLPTR, "expected mePtr to be NULL");
    CacheableKeyPtr keyPtr = CacheableKey::create(fwtest_Name);
    ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
    LRUEntryFactory::singleton->newMapEntry(keyPtr, mePtr);
    ASSERT(mePtr != NULLPTR, "expected to not be null.");
    LRUMapEntryPtr lmePtr = dynCast<LRUMapEntryPtr>(mePtr);
    ASSERT(lmePtr != NULLPTR, "expected to cast successfully to LRUMapEntry.");
  }
END_TEST(LRUCheckMapEntryImplPtr)

BEGIN_TEST(LRURemoveTest)
  {
    CacheableStringPtr cst = createCacheable("200");
    CacheablePtr ct = cst;
    EntryFactory* entryFactory = LRUEntryFactory::singleton;
    EntriesMap* entries = new LRUEntriesMap(
        entryFactory, NULL, LRUAction::LOCAL_DESTROY, 20, false);
    entries->open();
    ASSERT(entries->size() == 0, "expected size 0.");
    CacheableKeyPtr keyPtr;
    MapEntryImplPtr me;
    keyPtr = CacheableKey::create(fwtest_Name);
    CacheablePtr oldValue;
    VersionTagPtr versionTag;
    entries->put(keyPtr, ct, me, oldValue, -1, 0, versionTag);
    ASSERT(entries->size() == 1, "expected size 1.");
    CacheableStringPtr myValuePtr;
    CacheablePtr cvPtr;
    (void)entries->remove(keyPtr, cvPtr, me, -1, versionTag, false);
    myValuePtr = dynCast<CacheableStringPtr>(cvPtr);
    ASSERT(entries->size() == 0, "expected size 0.");
    ASSERT(cvPtr != NULLPTR, "expected to not be null.");
    ASSERT(myValuePtr->operator==(*createCacheable("200")),
           "CustomerType with m_foobar 200.");

    (void)entries->remove(keyPtr, cvPtr, me, -1, versionTag, false);
    ASSERT(cvPtr == NULLPTR,
           "expected already removed, and null result should clear ptr.");
  }
END_TEST(LRURemoveTest)

BEGIN_TEST(LRUGetEntryTest)
  {
    CacheableStringPtr cst = createCacheable("200");
    CacheablePtr ct = cst;
    EntryFactory* entryFactory = LRUEntryFactory::singleton;
    EntriesMap* entries = new LRUEntriesMap(
        entryFactory, NULL, LRUAction::LOCAL_DESTROY, 20, false);
    entries->open();
    CacheableKeyPtr keyPtr;
    MapEntryImplPtr me;
    keyPtr = CacheableKey::create(fwtest_Name);
    ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
    CacheablePtr oldValue;
    VersionTagPtr versionTag;
    entries->put(keyPtr, ct, me, oldValue, -1, 0, versionTag);
    ASSERT(entries->size() == 1, "expected size 1.");
    MapEntryImplPtr mePtr;
    CacheablePtr cvPtr;
    entries->getEntry(keyPtr, mePtr, cvPtr);
    ASSERT(mePtr != NULLPTR, "should not be null.");
    CacheableStringPtr ctPtr;
    ctPtr = dynCast<CacheableStringPtr>(cvPtr);
    ASSERT(ctPtr->operator==(*cst),
           "Entry should have a CustomerType Value of 200");
    CacheableKeyPtr keyPtr1;
    mePtr->getKey(keyPtr1);
    ASSERT(keyPtr1->operator==(*keyPtr), "should have same key.");
  }
END_TEST(LRUGetEntryTest)

BEGIN_TEST(LRULimitEvictTest)
  {
    EntryFactory* entryFactory = LRUEntryFactory::singleton;
    EntriesMap* entries = new LRUEntriesMap(entryFactory, NULL,
                                            LRUAction::LOCAL_DESTROY, 5, false);
    entries->open();
    MapEntryImplPtr me;
    CacheablePtr ct = createCacheable("somevalue");
    CacheablePtr oldValue;
    CacheableKeyPtr keyPtr = CacheableKey::create("1");
    ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
    VersionTagPtr versionTag;
    entries->put(keyPtr, ct, me, oldValue, -1, 0, versionTag);
    ASSERT(entries->size() == 1, "expected size 1.");
    keyPtr = CacheableKey::create("2");
    ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
    entries->put(keyPtr, ct, me, oldValue, -1, 0, versionTag);
    ASSERT(entries->size() == 2, "expected size 2.");
    keyPtr = CacheableKey::create("3");
    ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
    entries->put(keyPtr, ct, me, oldValue, -1, 0, versionTag);
    ASSERT(entries->size() == 3, "expected size 3.");
    keyPtr = CacheableKey::create("4");
    ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
    entries->put(keyPtr, ct, me, oldValue, -1, 0, versionTag);
    ASSERT(entries->size() == 4, "expected size 4.");
    keyPtr = CacheableKey::create("5");
    ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
    entries->put(keyPtr, ct, me, oldValue, -1, 0, versionTag);
    ASSERT(entries->size() == 5, "expected size 5.");
    LOG("Map is now at the limit.");
    keyPtr = CacheableKey::create("6");
    ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
    LOG("About to spill over.");
    entries->put(keyPtr, ct, me, oldValue, -1, 0, versionTag);
    LOG("Spilled over.");
    ASSERT(entries->size() == 5, "expected size 5.");
    LOG("Limit was preserved.");
  }
END_TEST(LRULimitEvictTest)

#endif
