// Copyright 2019 The Marl Authors.
//
// Licensed 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
//
//     https://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 "marl_test.h"

#include "marl/pool.h"
#include "marl/waitgroup.h"

TEST_P(WithBoundScheduler, UnboundedPool_ConstructDestruct) {
  marl::UnboundedPool<int> pool;
}

TEST_P(WithBoundScheduler, BoundedPool_ConstructDestruct) {
  marl::BoundedPool<int, 10> pool;
}

TEST_P(WithBoundScheduler, UnboundedPool_Borrow) {
  marl::UnboundedPool<int> pool;
  for (int i = 0; i < 100; i++) {
    pool.borrow();
  }
}

TEST_P(WithBoundScheduler, UnboundedPool_ConcurrentBorrow) {
  marl::UnboundedPool<int> pool;
  constexpr int iterations = 10000;
  marl::WaitGroup wg(iterations);
  for (int i = 0; i < iterations; i++) {
    marl::schedule([=] {
      pool.borrow();
      wg.done();
    });
  }
  wg.wait();
}

TEST_P(WithBoundScheduler, BoundedPool_Borrow) {
  marl::BoundedPool<int, 100> pool;
  for (int i = 0; i < 100; i++) {
    pool.borrow();
  }
}

TEST_P(WithBoundScheduler, BoundedPool_ConcurrentBorrow) {
  marl::BoundedPool<int, 10> pool;
  constexpr int iterations = 10000;
  marl::WaitGroup wg(iterations);
  for (int i = 0; i < iterations; i++) {
    marl::schedule([=] {
      pool.borrow();
      wg.done();
    });
  }
  wg.wait();
}

struct CtorDtorCounter {
  CtorDtorCounter() { ctor_count++; }
  ~CtorDtorCounter() { dtor_count++; }
  static void reset() {
    ctor_count = 0;
    dtor_count = 0;
  }
  static int ctor_count;
  static int dtor_count;
};

int CtorDtorCounter::ctor_count = -1;
int CtorDtorCounter::dtor_count = -1;

TEST_P(WithBoundScheduler, UnboundedPool_PolicyReconstruct) {
  CtorDtorCounter::reset();
  marl::UnboundedPool<CtorDtorCounter, marl::PoolPolicy::Reconstruct> pool;
  ASSERT_EQ(CtorDtorCounter::ctor_count, 0);
  ASSERT_EQ(CtorDtorCounter::dtor_count, 0);
  {
    auto loan = pool.borrow();
    ASSERT_EQ(CtorDtorCounter::ctor_count, 1);
    ASSERT_EQ(CtorDtorCounter::dtor_count, 0);
  }
  ASSERT_EQ(CtorDtorCounter::ctor_count, 1);
  ASSERT_EQ(CtorDtorCounter::dtor_count, 1);
  {
    auto loan = pool.borrow();
    ASSERT_EQ(CtorDtorCounter::ctor_count, 2);
    ASSERT_EQ(CtorDtorCounter::dtor_count, 1);
  }
  ASSERT_EQ(CtorDtorCounter::ctor_count, 2);
  ASSERT_EQ(CtorDtorCounter::dtor_count, 2);
}

TEST_P(WithBoundScheduler, BoundedPool_PolicyReconstruct) {
  CtorDtorCounter::reset();
  marl::BoundedPool<CtorDtorCounter, 10, marl::PoolPolicy::Reconstruct> pool;
  ASSERT_EQ(CtorDtorCounter::ctor_count, 0);
  ASSERT_EQ(CtorDtorCounter::dtor_count, 0);
  {
    auto loan = pool.borrow();
    ASSERT_EQ(CtorDtorCounter::ctor_count, 1);
    ASSERT_EQ(CtorDtorCounter::dtor_count, 0);
  }
  ASSERT_EQ(CtorDtorCounter::ctor_count, 1);
  ASSERT_EQ(CtorDtorCounter::dtor_count, 1);
  {
    auto loan = pool.borrow();
    ASSERT_EQ(CtorDtorCounter::ctor_count, 2);
    ASSERT_EQ(CtorDtorCounter::dtor_count, 1);
  }
  ASSERT_EQ(CtorDtorCounter::ctor_count, 2);
  ASSERT_EQ(CtorDtorCounter::dtor_count, 2);
}

TEST_P(WithBoundScheduler, UnboundedPool_PolicyPreserve) {
  CtorDtorCounter::reset();
  {
    marl::UnboundedPool<CtorDtorCounter, marl::PoolPolicy::Preserve> pool;
    int ctor_count;
    {
      auto loan = pool.borrow();
      ASSERT_NE(CtorDtorCounter::ctor_count, 0);
      ASSERT_EQ(CtorDtorCounter::dtor_count, 0);
      ctor_count = CtorDtorCounter::ctor_count;
    }
    ASSERT_EQ(CtorDtorCounter::ctor_count, ctor_count);
    ASSERT_EQ(CtorDtorCounter::dtor_count, 0);
    {
      auto loan = pool.borrow();
      ASSERT_EQ(CtorDtorCounter::ctor_count, ctor_count);
      ASSERT_EQ(CtorDtorCounter::dtor_count, 0);
    }
    ASSERT_EQ(CtorDtorCounter::ctor_count, ctor_count);
    ASSERT_EQ(CtorDtorCounter::dtor_count, 0);
  }
  ASSERT_EQ(CtorDtorCounter::ctor_count, CtorDtorCounter::dtor_count);
}

TEST_P(WithBoundScheduler, BoundedPool_PolicyPreserve) {
  CtorDtorCounter::reset();
  {
    marl::BoundedPool<CtorDtorCounter, 10, marl::PoolPolicy::Preserve> pool;
    int ctor_count;
    {
      auto loan = pool.borrow();
      ASSERT_NE(CtorDtorCounter::ctor_count, 0);
      ASSERT_EQ(CtorDtorCounter::dtor_count, 0);
      ctor_count = CtorDtorCounter::ctor_count;
    }
    ASSERT_EQ(CtorDtorCounter::ctor_count, ctor_count);
    ASSERT_EQ(CtorDtorCounter::dtor_count, 0);
    {
      auto loan = pool.borrow();
      ASSERT_EQ(CtorDtorCounter::ctor_count, ctor_count);
      ASSERT_EQ(CtorDtorCounter::dtor_count, 0);
    }
    ASSERT_EQ(CtorDtorCounter::ctor_count, ctor_count);
    ASSERT_EQ(CtorDtorCounter::dtor_count, 0);
  }
  ASSERT_EQ(CtorDtorCounter::ctor_count, CtorDtorCounter::dtor_count);
}
