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

#include <geode/ExceptionTypes.hpp>

#include "ExpiryTaskManager.hpp"
#include "gmock_extensions.h"
#include "mock/MockExpiryTask.hpp"
#include "util/concurrent/binary_semaphore.hpp"

using ::testing::DoAll;
using ::testing::InvokeWithoutArgs;
using ::testing::Return;
using ::testing::Sequence;

using apache::geode::client::binary_semaphore;

using apache::geode::client::ExpiryTask;
using apache::geode::client::ExpiryTaskManager;
using apache::geode::client::IllegalStateException;
using apache::geode::client::MockExpiryTask;

constexpr std::chrono::milliseconds DEFAULT_TIMEOUT{100};

TEST(ExpiryTaskTest, scheduleSingleshot) {
  binary_semaphore sem{0};
  ExpiryTaskManager manager;
  EXPECT_NO_THROW(manager.start());

  auto task = std::make_shared<MockExpiryTask>(manager);
  EXPECT_CALL(*task, on_expire())
      .Times(1)
      .WillOnce(DoAll(ReleaseSem(&sem), Return(true)));

  auto id = manager.schedule(std::move(task), std::chrono::seconds(0));
  EXPECT_NE(id, ExpiryTask::invalid());

  EXPECT_TRUE(sem.try_acquire_for(DEFAULT_TIMEOUT));

  EXPECT_NO_THROW(manager.stop());
}

TEST(ExpiryTaskTest, schedulePeriodic) {
  binary_semaphore sem{0};
  ExpiryTaskManager manager;

  EXPECT_NO_THROW(manager.start());

  auto task = std::make_shared<MockExpiryTask>(manager);
  {
    Sequence s;
    EXPECT_CALL(*task, on_expire())
        .Times(1)
        .InSequence(s)
        .WillOnce(Return(true));
    EXPECT_CALL(*task, on_expire())
        .Times(1)
        .InSequence(s)
        .WillOnce(DoAll(ReleaseSem(&sem), Return(true)));
    EXPECT_CALL(*task, on_expire()).InSequence(s).WillRepeatedly(Return(true));
  }
  auto id = manager.schedule(std::move(task), std::chrono::seconds(0),
                             std::chrono::nanoseconds(1));
  EXPECT_NE(id, ExpiryTask::invalid());

  EXPECT_TRUE(sem.try_acquire_for(DEFAULT_TIMEOUT));

  EXPECT_NO_THROW(manager.stop());
}

TEST(ExpiryTaskTest, resetSingleshot) {
  binary_semaphore sem{0};
  ExpiryTaskManager manager;

  EXPECT_NO_THROW(manager.start());

  auto task = std::make_shared<MockExpiryTask>(manager);
  auto& task_ref = *task;

  {
    Sequence s;
    EXPECT_CALL(task_ref, on_expire())
        .Times(1)
        .InSequence(s)
        .WillOnce(InvokeWithoutArgs([&task_ref] {
          task_ref.reset(std::chrono::nanoseconds(1));
          return false;
        }));
    EXPECT_CALL(task_ref, on_expire())
        .Times(1)
        .InSequence(s)
        .WillOnce(DoAll(ReleaseSem(&sem), Return(true)));
  }

  auto id = manager.schedule(std::move(task), std::chrono::seconds(0));
  EXPECT_NE(id, ExpiryTask::invalid());

  EXPECT_TRUE(sem.try_acquire_for(DEFAULT_TIMEOUT));

  EXPECT_NO_THROW(manager.stop());
}

TEST(ExpiryTaskTest, resetPeriodic) {
  binary_semaphore sem{0};
  ExpiryTaskManager manager;

  EXPECT_NO_THROW(manager.start());

  auto task = std::make_shared<MockExpiryTask>(manager);
  auto& task_ref = *task;

  {
    Sequence s;
    EXPECT_CALL(task_ref, on_expire())
        .Times(1)
        .InSequence(s)
        .WillOnce(InvokeWithoutArgs([&task_ref] {
          task_ref.reset(std::chrono::nanoseconds(1));
          return false;
        }));
    EXPECT_CALL(task_ref, on_expire())
        .InSequence(s)
        .WillRepeatedly(DoAll(ReleaseSem(&sem), Return(true)));
  }
  auto id = manager.schedule(std::move(task), std::chrono::seconds(0));
  EXPECT_NE(id, ExpiryTask::invalid());

  EXPECT_TRUE(sem.try_acquire_for(DEFAULT_TIMEOUT));

  EXPECT_NO_THROW(manager.stop());
}
