/*
 * 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 <geode/ExpirationAction.hpp>
#include <geode/Region.hpp>

#include "fw_helper.hpp"
#include "CacheRegionHelper.hpp"
#include "CacheImpl.hpp"

using apache::geode::client::Cache;
using apache::geode::client::CacheableKey;
using apache::geode::client::CacheableString;
using apache::geode::client::CacheFactory;
using apache::geode::client::CacheRegionHelper;
using apache::geode::client::ExpirationAction;
using apache::geode::client::Properties;
using apache::geode::client::Region;
using apache::geode::client::RegionAttributes;
using apache::geode::client::RegionAttributesFactory;

ExpirationAction action = ExpirationAction::DESTROY;

// This test is for serially running the tests.

size_t getNumOfEntries(std::shared_ptr<Region> &R1) {
  std::vector<std::shared_ptr<CacheableKey>> v = R1->keys();
  LOGFINE("Number of keys in region %s is %d", R1->getFullPath().c_str(),
          v.size());
  return v.size();
}

void startDSandCreateCache(std::shared_ptr<Cache> &cache) {
  auto pp = Properties::create();
  auto cacheFactory = CacheFactory(pp);
  cacheFactory.set("statistic-sampling-enabled", "true");
  cache = std::make_shared<Cache>(cacheFactory.create());
  ASSERT(cache != nullptr, "cache not equal to null expected");
}

void doNPuts(std::shared_ptr<Region> &rptr, int n) {
  std::shared_ptr<CacheableString> value;
  char buf[16];
  memset(buf, 'A', 15);
  buf[15] = '\0';
  memcpy(buf, "Value - ", 8);
  value = CacheableString::create(buf);
  ASSERT(value != nullptr, "Failed to create value.");

  for (int i = 0; i < n; i++) {
    sprintf(buf, "KeyA - %d", i + 1);
    auto key = CacheableKey::create(buf);
    LOGINFO("Putting key %s value %s in region %s", buf,
            value->toString().c_str(), rptr->getFullPath().c_str());
    rptr->put(key, value);
  }
}
std::shared_ptr<CacheableKey> do1Put(std::shared_ptr<Region> &rptr) {
  std::shared_ptr<CacheableString> value;
  char buf[16];
  memset(buf, 'A', 15);
  buf[15] = '\0';
  memcpy(buf, "Value - ", 8);
  value = CacheableString::create(buf);
  ASSERT(value != nullptr, "Failed to create value.");

  sprintf(buf, "KeyA - %d", 0 + 1);
  auto key = CacheableKey::create(buf);
  LOGINFO("Putting key %s value %s in region %s", buf,
          value->toString().c_str(), rptr->getFullPath().c_str());
  rptr->put(key, value);
  return key;
}

RegionAttributes setRegionAttributesTimeouts(
    const std::chrono::seconds &entryTimeToLive = std::chrono::seconds::zero(),
    const std::chrono::seconds &entryIdleTimeout = std::chrono::seconds::zero(),
    const std::chrono::seconds &regionTimeToLive = std::chrono::seconds::zero(),
    const std::chrono::seconds &regionIdleTimeout =
        std::chrono::seconds::zero()) {
  RegionAttributesFactory regionAttributesFactory;

  regionAttributesFactory.setEntryTimeToLive(action, entryTimeToLive);
  regionAttributesFactory.setEntryIdleTimeout(action, entryIdleTimeout);
  regionAttributesFactory.setRegionTimeToLive(action, regionTimeToLive);
  regionAttributesFactory.setRegionIdleTimeout(action, regionIdleTimeout);

  return regionAttributesFactory.create();
}

BEGIN_TEST(TEST_EXPIRATION)
  {
    std::shared_ptr<Cache> cache;

    startDSandCreateCache(cache);

    ASSERT(cache != nullptr, "Expected cache to be NON-nullptr");

    ASSERT(cache->getSystemProperties().statisticsEnabled(),
           "Statistics must be enabled for expiration.");

    auto cacheImpl = CacheRegionHelper::getCacheImpl(cache.get());

    size_t n;

    RegionAttributes attrs_1;
    // ettl = 0, eit = 0, rttl = 0, reit = 0
    attrs_1 = setRegionAttributesTimeouts();
    std::shared_ptr<Region> R1;
    cacheImpl->createRegion("R1", attrs_1, R1);
    ASSERT(R1 != nullptr, "Expected R1 to be NON-nullptr");

    doNPuts(R1, 100);

    ACE_OS::sleep(10);

    n = getNumOfEntries(R1);
    ASSERT(n == 100, "Expected 100 entries");

    ASSERT(R1->isDestroyed() == false, "Expected R1 to be alive");

    RegionAttributes attrs_2;

    attrs_2 = setRegionAttributesTimeouts(
        std::chrono::seconds(20), std::chrono::seconds(2),
        std::chrono::seconds(0), std::chrono::seconds(0));

    std::shared_ptr<Region> R2;
    cacheImpl->createRegion("R2", attrs_2, R2);
    ASSERT(R2 != nullptr, "Expected R2 to be NON-nullptr");
    LOG("Region R2 created");
    doNPuts(R2, 1);

    ACE_OS::sleep(5);

    n = getNumOfEntries(R2);
    ASSERT(n == 1, "Expected 1 entry");

    ASSERT(R2->isDestroyed() == false, "Expected R2 to be alive");

    RegionAttributes attrs_3;
    // rttl = 20, reit = 2
    attrs_3 = setRegionAttributesTimeouts(
        std::chrono::seconds(0), std::chrono::seconds(0),
        std::chrono::seconds(20), std::chrono::seconds(2));

    std::shared_ptr<Region> R3;
    cacheImpl->createRegion("R3", attrs_3, R3);
    ASSERT(R3 != nullptr, "Expected R3 to be NON-nullptr");

    ACE_OS::sleep(5);

    ASSERT(R3->isDestroyed() == false, "Expected R3 to be alive");

    RegionAttributes attrs_4;

    attrs_4 = setRegionAttributesTimeouts(
        std::chrono::seconds(5), std::chrono::seconds(0),
        std::chrono::seconds(0), std::chrono::seconds(0));

    std::shared_ptr<Region> R4;
    cacheImpl->createRegion("R4", attrs_4, R4);
    ASSERT(R4 != nullptr, "Expected R4 to be NON-nullptr");

    doNPuts(R4, 1);
    // This will be same as updating the object

    ACE_OS::sleep(10);

    n = getNumOfEntries(R4);
    ASSERT(n == 0, "Expected 0 entry");

    ASSERT(R4->isDestroyed() == false, "Expected R4 to be alive");

    RegionAttributes attrs_5;
    // ettl = 0, eit = 0, rttl = 0, reit = 0
    attrs_5 = setRegionAttributesTimeouts(
        std::chrono::seconds(0), std::chrono::seconds(5),
        std::chrono::seconds(0), std::chrono::seconds(0));

    std::shared_ptr<Region> R5;
    cacheImpl->createRegion("R5", attrs_5, R5);
    ASSERT(R5 != nullptr, "Expected R5 to be NON-nullptr");

    auto key_0 = do1Put(R5);

    ACE_OS::sleep(2);

    R5->get(key_0);
    ACE_OS::sleep(3);

    n = getNumOfEntries(R5);

    printf("n ==  %zd\n", n);
    ASSERT(n == 1, "Expected 1 entry");

    // ACE_OS::sleep(3);
    ACE_OS::sleep(6);
    n = getNumOfEntries(R5);

    ASSERT(n == 0, "Expected 0 entry");
    ASSERT(R5->isDestroyed() == false, "Expected R5 to be alive");

    RegionAttributes attrs_6;
    // ettl = 0, eit = 0, rttl = 0, reit = 0
    attrs_6 = setRegionAttributesTimeouts(
        std::chrono::seconds(0), std::chrono::seconds(0),
        std::chrono::seconds(5), std::chrono::seconds(0));

    std::shared_ptr<Region> R6;
    cacheImpl->createRegion("R6", attrs_6, R6);
    ASSERT(R6 != nullptr, "Expected R6 to be NON-nullptr");

    doNPuts(R6, 1);

    ACE_OS::sleep(2);

    doNPuts(R6, 1);

    ACE_OS::sleep(7);

    ASSERT(R6->isDestroyed() == true, "Expected R6 to be dead");

    RegionAttributes attrs_7;
    // ettl = 0, eit = 0, rttl = 0, reit = 0
    attrs_7 = setRegionAttributesTimeouts(
        std::chrono::seconds(0), std::chrono::seconds(0),
        std::chrono::seconds(0), std::chrono::seconds(5));

    std::shared_ptr<Region> R7;
    cacheImpl->createRegion("R7", attrs_7, R7);
    ASSERT(R7 != nullptr, "Expected R7 to be NON-nullptr");

    doNPuts(R7, 1);

    ACE_OS::sleep(2);

    doNPuts(R7, 1);

    ACE_OS::sleep(10);

    ASSERT(R7->isDestroyed() == true, "Expected R7 to be dead");

    RegionAttributes attrs_8;
    // ettl = 0, eit = 0, rttl = 0, reit = 0
    attrs_8 = setRegionAttributesTimeouts(
        std::chrono::seconds(10), std::chrono::seconds(0),
        std::chrono::seconds(0), std::chrono::seconds(0));

    std::shared_ptr<Region> R8;
    cacheImpl->createRegion("R8", attrs_8, R8);
    ASSERT(R8 != nullptr, "Expected R8 to be NON-nullptr");

    auto key = do1Put(R8);

    ACE_OS::sleep(5);

    R8->get(key);

    ACE_OS::sleep(6);

    n = getNumOfEntries(R8);
    ASSERT(n == 0, "Expected 1 entries");

    RegionAttributes attrs_9;
    // ettl = 0, eit = 0, rttl = 0, reit = 0
    attrs_9 = setRegionAttributesTimeouts(
        std::chrono::seconds(0), std::chrono::seconds(0),
        std::chrono::seconds(0), std::chrono::seconds(8));

    std::shared_ptr<Region> R9;
    cacheImpl->createRegion("R9", attrs_9, R9);
    ASSERT(R9 != nullptr, "Expected R9 to be NON-nullptr");

    auto key_1 = do1Put(R9);

    ACE_OS::sleep(5);

    R9->get(key_1);

    ACE_OS::sleep(5);

    n = getNumOfEntries(R9);
    ASSERT(n == 1, "Expected 1 entries");

    ASSERT(R9->isDestroyed() == false, "Expected R9 to be alive");

    RegionAttributes attrs_10;
    // ettl = 0, eit = 0, rttl = 0, reit = 0
    attrs_10 = setRegionAttributesTimeouts(
        std::chrono::seconds(6), std::chrono::seconds(0),
        std::chrono::seconds(0), std::chrono::seconds(12));

    std::shared_ptr<Region> R10;
    cacheImpl->createRegion("R10", attrs_10, R10);
    ASSERT(R10 != nullptr, "Expected R10 to be NON-nullptr");

    doNPuts(R10, 1);

    ACE_OS::sleep(10);

    n = getNumOfEntries(R10);
    ASSERT(n == 0, "Expected 0 entries");

    ACE_OS::sleep(11);

    ASSERT(R10->isDestroyed() == true, "Expected R10 to be dead");

    RegionAttributes attrs_11;

    // ettl = 0, eit = 0, rttl = 0, reit = 0
    attrs_11 = setRegionAttributesTimeouts(
        std::chrono::seconds(0), std::chrono::seconds(4),
        std::chrono::seconds(0), std::chrono::seconds(7));

    std::shared_ptr<Region> R11;
    cacheImpl->createRegion("R11", attrs_11, R11);
    ASSERT(R11 != nullptr, "Expected R11 to be NON-nullptr");

    auto k11 = do1Put(R11);

    ACE_OS::sleep(3);

    n = getNumOfEntries(R11);
    ASSERT(n == 1, "Expected 1 entries");

    R11->get(k11);

    ACE_OS::sleep(5);

    ASSERT(R11->isDestroyed() == false,
           "Expected R11 to be alive as the get has changed the access time");

    ACE_OS::sleep(5);

    ASSERT(R11->isDestroyed() == true, "Expected R11 to be dead");

    RegionAttributes attrs_12;
    // ettl = 0, eit = 0, rttl = 0, reit = 0
    attrs_12 = setRegionAttributesTimeouts(
        std::chrono::seconds(5), std::chrono::seconds(0),
        std::chrono::seconds(0), std::chrono::seconds(0));

    std::shared_ptr<Region> R12;
    cacheImpl->createRegion("R12", attrs_12, R12);
    ASSERT(R12 != nullptr, "Expected R12 to be NON-nullptr");

    auto key_3 = do1Put(R12);

    ACE_OS::sleep(6);

    n = getNumOfEntries(R12);
    ASSERT(n == 0, "Expected 0 entries");

    ASSERT(R12->isDestroyed() == false, "Expected R12 to be alive");
    /////////

    RegionAttributes attrs_14;
    // ettl = 0, eit = 0, rttl = 0, reit = 0
    attrs_14 = setRegionAttributesTimeouts(
        std::chrono::seconds(0), std::chrono::seconds(0),
        std::chrono::seconds(10), std::chrono::seconds(0));

    std::shared_ptr<Region> R14;
    cacheImpl->createRegion("R14", attrs_14, R14);
    ASSERT(R14 != nullptr, "Expected R14 to be NON-nullptr");

    doNPuts(R14, 1);

    ACE_OS::sleep(12);

    ASSERT(R14->isDestroyed() == true, "Expected R14 to be dead");

    RegionAttributes attrs_15;
    // ettl = 0, eit = 0, rttl = 0, reit = 0
    attrs_15 = setRegionAttributesTimeouts(
        std::chrono::seconds(0), std::chrono::seconds(5),
        std::chrono::seconds(0), std::chrono::seconds(0));

    std::shared_ptr<Region> R15;
    cacheImpl->createRegion("R15", attrs_15, R15);
    ASSERT(R15 != nullptr, "Expected R15 to be NON-nullptr");

    auto key_4 = do1Put(R15);

    ACE_OS::sleep(2);

    R15->destroy(key_4);

    ACE_OS::sleep(5);

    ASSERT(R15->isDestroyed() == false, "Expected R15 to be alive");

    //////////////
    RegionAttributes attrs_18;
    // ettl = 0, eit = 0, rttl = 0, reit = 0
    attrs_18 = setRegionAttributesTimeouts(
        std::chrono::seconds(6), std::chrono::seconds(3),
        std::chrono::seconds(0), std::chrono::seconds(0));

    std::shared_ptr<Region> R18;
    cacheImpl->createRegion("R18", attrs_18, R18);
    ASSERT(R18 != nullptr, "Expected R18 to be NON-nullptr");

    doNPuts(R18, 1);

    ACE_OS::sleep(4);

    n = getNumOfEntries(R18);
    ASSERT(n == 1, "entry idle should be useless as ttl is > 0");

    ACE_OS::sleep(4);
    n = getNumOfEntries(R18);
    ASSERT(n == 0, "ttl is over so it should be 0");

    RegionAttributes attrs_19;
    // ettl = 0, eit = 0, rttl = 0, reit = 0
    attrs_19 = setRegionAttributesTimeouts(
        std::chrono::seconds(0), std::chrono::seconds(0),
        std::chrono::seconds(6), std::chrono::seconds(3));

    std::shared_ptr<Region> R19;
    cacheImpl->createRegion("R19x", attrs_19, R19);
    ASSERT(R19 != nullptr, "Expected R19 to be NON-nullptr");

    ACE_OS::sleep(4);

    doNPuts(R19, 1);

    ACE_OS::sleep(4);

    ASSERT(R19->isDestroyed() == false,
           "Expected R19 to be alive as an entry was put");

    ACE_OS::sleep(4);

    ASSERT(R19->isDestroyed() == true, "Expected R19 to be dead");
    cache->close();
  }
END_TEST(TEST_EXPIRATION)
