/**
 * 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 "transaction/Lock.hpp"

#include <cstddef>
#include <memory>
#include <vector>

#include "transaction/AccessMode.hpp"
#include "transaction/ResourceId.hpp"

#include "gtest/gtest.h"

namespace quickstep {
namespace transaction {

class LockTest : public ::testing::Test {
 protected:
  LockTest()
      : modes_({AccessMode::NoLockMode(),
                AccessMode::IsLockMode(),
                AccessMode::IxLockMode(),
                AccessMode::SLockMode(),
                AccessMode::SixLockMode(),
                AccessMode::XLockMode()}),
        resource_a_(3, 10, 2, 5),
        resource_b_(4, 5, 3, 2),
        locks_on_resource_a_({Lock(resource_a_, modes_[0]),
                              Lock(resource_a_, modes_[1]),
                              Lock(resource_a_, modes_[2]),
                              Lock(resource_a_, modes_[3]),
                              Lock(resource_a_, modes_[4]),
                              Lock(resource_a_, modes_[5])}),
        locks_on_resource_b_({Lock(resource_b_, modes_[0]),
                             Lock(resource_b_, modes_[1]),
                             Lock(resource_b_, modes_[2]),
                             Lock(resource_b_, modes_[3]),
                             Lock(resource_b_, modes_[4]),
                             Lock(resource_b_, modes_[5])}) {
  }

  const std::vector<AccessMode> modes_;
  const ResourceId resource_a_;
  const ResourceId resource_b_;
  const std::vector<Lock> locks_on_resource_a_;
  const std::vector<Lock> locks_on_resource_b_;
};

TEST_F(LockTest, LockEquality) {
  // Locks are equal if they are on the same resource with same
  // access mode.
  for (std::size_t i = 0; i < locks_on_resource_a_.size(); ++i) {
    for (std::size_t j = 0; j < locks_on_resource_a_.size(); ++j) {
      if (i == j) {
        EXPECT_EQ(locks_on_resource_a_[i], locks_on_resource_a_[j]);
      } else {
        EXPECT_NE(locks_on_resource_a_[i], locks_on_resource_a_[j]);
      }
    }
    // Locks are nver equal if they have different resource ids.
    EXPECT_NE(locks_on_resource_a_[i], locks_on_resource_b_[i]);
  }
}

TEST_F(LockTest, GetResourceId) {
  for (std::size_t i = 0; i < locks_on_resource_a_.size(); ++i) {
    EXPECT_EQ(resource_a_, locks_on_resource_a_[i].getResourceId());
  }
}

TEST_F(LockTest, GetAccessMode) {
  for (std::size_t i = 0; i < locks_on_resource_a_.size(); ++i) {
    EXPECT_EQ(modes_[i], locks_on_resource_a_[i].getAccessMode());
  }
}

}  // namespace transaction
}  // namespace quickstep
