// Copyright 2023 Google LLC
//
// 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 "mpact/sim/generic/simple_resource.h"

#include <memory>

#include "googlemock/include/gmock/gmock.h"
#include "googletest/include/gtest/gtest.h"

using testing::StrEq;

namespace mpact {
namespace sim {
namespace generic {
namespace {

// Will run the test on a single resource pool, with three resource instances.
static constexpr char kTestPoolName[] = "TestPool";
static constexpr int kTestPoolSize = 35;
static constexpr int kNumResources = 3;
static constexpr char kTestResource0[] = "Resource0";
static constexpr char kTestResource1[] = "Resource1";
static constexpr char kTestResource2[] = "Resource2";
static constexpr char const* kTestResources[] = {kTestResource0, kTestResource1,
                                                 kTestResource2};

class SimpleResourceTest : public testing::Test {
 protected:
  SimpleResourceTest() {
    pool_ = std::make_unique<SimpleResourcePool>(kTestPoolName, kTestPoolSize);
  }
  ~SimpleResourceTest() override {}

  std::unique_ptr<SimpleResourcePool> pool_;
};

TEST_F(SimpleResourceTest, Instantiation) {
  EXPECT_THAT(pool_->name(), StrEq(kTestPoolName));
  EXPECT_EQ(pool_->width(), kTestPoolSize);
  EXPECT_EQ(pool_->resource_vector().GetOnesCount(), 0);
}

TEST_F(SimpleResourceTest, Resources) {
  SimpleResource* resources[kNumResources];
  for (int num = 0; num < kNumResources; num++) {
    const char* name = kTestResources[num];
    // Creat resource.
    EXPECT_TRUE(pool_->AddResource(name).ok());
    resources[num] = pool_->GetResource(name);
    EXPECT_THAT(resources[num]->name(), StrEq(name));
    // Verify resource properties.
    EXPECT_EQ(resources[num]->index(), num);
    EXPECT_EQ(resources[num]->resource_bit().GetOnesCount(), 1);
    int position;
    EXPECT_TRUE(resources[num]->resource_bit().FindFirstSetBit(&position));
    EXPECT_EQ(position, num);
    // Try reserving resource and free it.
    EXPECT_TRUE(resources[num]->IsFree());
    resources[num]->Acquire();
    EXPECT_EQ(pool_->resource_vector().GetOnesCount(), 1);
    EXPECT_TRUE(resources[num]->resource_bit().FindFirstSetBit(&position));
    EXPECT_EQ(position, num);
    EXPECT_FALSE(resources[num]->IsFree());
    resources[num]->Release();
    EXPECT_EQ(pool_->resource_vector().GetOnesCount(), 0);
  }
  for (int num = 0; num < kNumResources; num++) {
    resources[num]->Acquire();
    EXPECT_EQ(pool_->resource_vector().GetOnesCount(), num + 1);
  }
}

TEST_F(SimpleResourceTest, ResourceSets) {
  SimpleResource* resources[kNumResources];
  for (int num = 0; num < kNumResources; num++) {
    const char* name = kTestResources[num];
    // Creat resource.
    EXPECT_TRUE(pool_->AddResource(name).ok());
    resources[num] = pool_->GetResource(name);
  }

  // Create a resource set and add resource 0 and 1 to it.
  SimpleResourceSet* resource_set = pool_->CreateResourceSet();
  EXPECT_TRUE(resource_set->AddResource(kTestResource0).ok());
  EXPECT_TRUE(resource_set->AddResource(resources[1]).ok());

  // Acquire resource 2.
  resources[2]->Acquire();
  EXPECT_TRUE(resource_set->IsFree());
  // Acquire resource 1.
  resources[1]->Acquire();
  EXPECT_FALSE(resource_set->IsFree());
  // Release resource 1.
  resources[1]->Release();

  // Acquire the resource set.
  resource_set->Acquire();
  // All resources should now be reserved.
  EXPECT_EQ(pool_->resource_vector().GetOnesCount(), 3);
  EXPECT_FALSE(resources[0]->IsFree());
  EXPECT_FALSE(resources[1]->IsFree());
  EXPECT_FALSE(resources[2]->IsFree());

  // Release the resource set. Resource 2 should still be reserved.
  resource_set->Release();
  EXPECT_EQ(pool_->resource_vector().GetOnesCount(), 1);
  EXPECT_TRUE(resources[0]->IsFree());
  EXPECT_TRUE(resources[1]->IsFree());
  EXPECT_FALSE(resources[2]->IsFree());
  EXPECT_TRUE(resource_set->IsFree());
}

}  // namespace
}  // namespace generic
}  // namespace sim
}  // namespace mpact
