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

#include "fw_helper.hpp"

#define ROOT_NAME "testRegionMap"

#include "CacheHelper.hpp"

using apache::geode::client::CacheableKey;
using apache::geode::client::CacheableString;
using apache::geode::client::CacheHelper;
using apache::geode::client::Region;

/**
 * @brief Test putting and getting entries without LRU enabled.
 */
BEGIN_TEST(TestRegionLRULastTen)
#if 1
  CacheHelper& cacheHelper = CacheHelper::getHelper();
  std::shared_ptr<Region> regionPtr;
  cacheHelper.createLRURegion(fwtest_Name, regionPtr);
  std::cout << regionPtr->getFullPath() << std::endl;
  // put more than 10 items... verify limit is held.
  uint32_t i;
  for (i = 0; i < 10; i++) {
    char buf[100];
    sprintf(buf, "%d", i);
    auto key = CacheableKey::create(buf);
    sprintf(buf, "value of %d", i);
    auto valuePtr = cacheHelper.createCacheable(buf);
    regionPtr->put(key, valuePtr);
    auto&& vecKeys = regionPtr->keys();
    ASSERT(vecKeys.size() == (i + 1), "expected more entries");
  }
  for (i = 10; i < 20; i++) {
    char buf[100];
    sprintf(buf, "%d", i);
    auto key = CacheableKey::create(buf);
    sprintf(buf, "value of %d", i);
    auto valuePtr = cacheHelper.createCacheable(buf);
    regionPtr->put(key, valuePtr);
    auto&& vecKeys = regionPtr->keys();
    cacheHelper.showKeys(vecKeys);
    ASSERT(vecKeys.size() == (10), "expected 10 entries");
  }
  auto&& vecKeys = regionPtr->keys();
  ASSERT(vecKeys.size() == 10, "expected 10 entries");
  // verify it is the last 10 keys..
  int expected = 0;
  int total = 0;
  for (int k = 10; k < 20; k++) {
    expected += k;
    auto key = std::dynamic_pointer_cast<CacheableString>(vecKeys.back());
    vecKeys.pop_back();
    total += atoi(key->value().c_str());
  }
  ASSERT(vecKeys.empty(), "expected no more than 10 keys.");
  ASSERT(expected == total, "checksum mismatch.");
#endif
END_TEST(TestRegionLRULastTen)

BEGIN_TEST(TestRegionNoLRU)
#if 1
  CacheHelper& cacheHelper = CacheHelper::getHelper();
  std::shared_ptr<Region> regionPtr;
  cacheHelper.createPlainRegion(fwtest_Name, regionPtr);
  // put more than 10 items... verify limit is held.
  uint32_t i;
  for (i = 0; i < 20; i++) {
    char buf[100];
    sprintf(buf, "%d", i);
    auto key = CacheableKey::create(buf);
    sprintf(buf, "value of %d", i);
    auto valuePtr = cacheHelper.createCacheable(buf);
    regionPtr->put(key, valuePtr);
    auto&& vecKeys = regionPtr->keys();
    cacheHelper.showKeys(vecKeys);
    ASSERT(vecKeys.size() == (i + 1), "unexpected entries count");
  }
#endif

END_TEST(TestRegionNoLRU)

BEGIN_TEST(TestRegionLRULocal)
#if 1
  CacheHelper& cacheHelper = CacheHelper::getHelper();
  std::shared_ptr<Region> regionPtr;
  cacheHelper.createLRURegion(fwtest_Name, regionPtr);
  std::cout << regionPtr->getFullPath() << std::endl;
  // put more than 10 items... verify limit is held.
  uint32_t i;
  /** @TODO make this local scope and re-increase the iterations... would also
   * like to time it. */
  for (i = 0; i < 1000; i++) {
    char buf[100];
    sprintf(buf, "%d", i);
    auto key = CacheableKey::create(buf);
    sprintf(buf, "value of %d", i);
    auto valuePtr = cacheHelper.createCacheable(buf);
    regionPtr->put(key, valuePtr);
    auto&& vecKeys = regionPtr->keys();
    ASSERT(vecKeys.size() == (i < 10 ? i + 1 : 10), "expected more entries");
  }
#endif
END_TEST(TestRegionLRULocal)

BEGIN_TEST(TestRecentlyUsedBit)
  // Put twenty items in region. LRU is set to 10.
  // So 10 through 19 should be in region (started at 0)
  // get 15 so it is marked recently used.
  // put 9 more...  check that 15 was skipped for eviction.
  // put 1 more...  15 should then have been evicted.
  CacheHelper& cacheHelper = CacheHelper::getHelper();
  std::shared_ptr<Region> regionPtr;
  cacheHelper.createLRURegion(fwtest_Name, regionPtr);
  std::cout << regionPtr->getFullPath() << std::endl;
  // put more than 10 items... verify limit is held.
  uint32_t i;
  char buf[100];
  for (i = 0; i < 20; i++) {
    sprintf(buf, "%d", i);
    auto key = CacheableKey::create(buf);
    sprintf(buf, "value of %d", i);
    auto valuePtr = cacheHelper.createCacheable(buf);
    regionPtr->put(key, valuePtr);
  }
  sprintf(buf, "%d", 15);
  std::shared_ptr<CacheableString> value2Ptr;
  auto key2 = CacheableKey::create(buf);
  value2Ptr = std::dynamic_pointer_cast<CacheableString>(regionPtr->get(key2));
  ASSERT(value2Ptr != nullptr, "expected to find key 15 in cache.");
  for (i = 20; i < 35; i++) {
    sprintf(buf, "%d", i);
    auto key = CacheableKey::create(buf);
    auto valuePtr = cacheHelper.createCacheable(buf);
    regionPtr->put(key, valuePtr);
    auto&& vecKeys = regionPtr->keys();
    cacheHelper.showKeys(vecKeys);
    ASSERT(vecKeys.size() == 10, "expected more entries");
  }
  ASSERT(regionPtr->containsKey(key2), "expected to find key 15 in cache.");
  {
    sprintf(buf, "%d", 35);
    auto key = CacheableKey::create(buf);
    auto valuePtr = cacheHelper.createCacheable(buf);
    regionPtr->put(key, valuePtr);
    auto&& vecKeys = regionPtr->keys();
    cacheHelper.showKeys(vecKeys);
    ASSERT(vecKeys.size() == 10, "expected more entries");
  }
  ASSERT(regionPtr->containsKey(key2) == false, "15 should have been evicted.");
END_TEST(TestRecentlyUsedBit)

BEGIN_TEST(TestEmptiedMap)
  CacheHelper& cacheHelper = CacheHelper::getHelper();
  std::shared_ptr<Region> regionPtr;
  cacheHelper.createLRURegion(fwtest_Name, regionPtr);
  std::cout << regionPtr->getFullPath() << std::endl;
  // put more than 10 items... verify limit is held.
  uint32_t i;
  for (i = 0; i < 10; i++) {
    char buf[100];
    sprintf(buf, "%d", i);
    auto key = CacheableKey::create(buf);
    sprintf(buf, "value of %d", i);
    auto valuePtr = cacheHelper.createCacheable(buf);
    regionPtr->put(key, valuePtr);
    auto&& vecKeys = regionPtr->keys();
    ASSERT(vecKeys.size() == (i + 1), "expected more entries");
  }
  for (i = 0; i < 10; i++) {
    char buf[100];
    sprintf(buf, "%d", i);
    auto key = CacheableKey::create(buf);
    regionPtr->destroy(key);
    std::cout
        << "removed key "
        << std::dynamic_pointer_cast<CacheableString>(key)->value().c_str()
        << std::endl;
  }
  auto&& vecKeys = regionPtr->keys();
  ASSERT(vecKeys.size() == 0, "expected more entries");
  for (i = 20; i < 40; i++) {
    char buf[100];
    sprintf(buf, "%d", i);
    auto key = CacheableKey::create(buf);
    sprintf(buf, "value of %d", i);
    auto valuePtr = cacheHelper.createCacheable(buf);
    regionPtr->put(key, valuePtr);
  }
  vecKeys = regionPtr->keys();
  ASSERT(vecKeys.size() == 10, "expected more entries");

  cacheHelper.resetHelper();

END_TEST(TestEmptiedMap)
