// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <lib/operation/helpers/alloc_checker.h>
#include <lib/operation/operation.h>

#include <memory>

#include <zxtest/zxtest.h>

namespace {

struct TestOp {
  int dummy;
};

struct TestOpTraits {
  using OperationType = TestOp;

  static OperationType* Alloc(size_t op_size) {
    operation::AllocChecker ac;
    std::unique_ptr<uint8_t[]> raw;
    if constexpr (alignof(OperationType) > __STDCPP_DEFAULT_NEW_ALIGNMENT__) {
      raw = std::unique_ptr<uint8_t[]>(
          new (static_cast<std::align_val_t>(alignof(OperationType)), &ac) uint8_t[op_size]);
    } else {
      raw = std::unique_ptr<uint8_t[]>(new (&ac) uint8_t[op_size]);
    }
    if (!ac.check()) {
      return nullptr;
    }
    return reinterpret_cast<TestOp*>(raw.release());
  }

  static void Free(OperationType* op) { delete[] reinterpret_cast<uint8_t*>(op); }
};

using TestOpCallback = void (*)(void*, zx_status_t, TestOp*);

struct CallbackTraits {
  using CallbackType = TestOpCallback;

  static void Callback(const CallbackType* callback, void* cookie, TestOp* op, zx_status_t status) {
    (*callback)(cookie, status, op);
  }
};

struct Operation : public operation::Operation<Operation, TestOpTraits, void> {
  using BaseClass = operation::Operation<Operation, TestOpTraits, void>;
  using BaseClass::BaseClass;
};

struct BorrowedOperation
    : public operation::BorrowedOperation<BorrowedOperation, TestOpTraits, CallbackTraits, void> {
  using BaseClass =
      operation::BorrowedOperation<BorrowedOperation, TestOpTraits, CallbackTraits, void>;
  using BaseClass::BaseClass;
};

using OperationList = operation::OperationList<Operation, TestOpTraits, void>;
using BorrowedOperationList =
    operation::BorrowedOperationList<BorrowedOperation, TestOpTraits, CallbackTraits, void>;

constexpr size_t kParentOpSize = sizeof(TestOp);

TEST(OperationListTest, TrivialLifetime) {
  OperationList list;
  BorrowedOperationList unowned_list;
}

TEST(OperationListTest, Move) {
  OperationList list;

  std::optional<Operation> opt_operation = Operation::Alloc(kParentOpSize);
  ASSERT_TRUE(opt_operation.has_value());
  Operation operation = *std::move(opt_operation);
  list.push_back(&operation);
  EXPECT_EQ(list.size(), 1u);

  OperationList list2(std::move(list));
  EXPECT_EQ(list2.size(), 1u);
  EXPECT_EQ(list.size(), 0u);
}

TEST(OperationListTest, SingleOperation) {
  std::optional<Operation> opt_operation = Operation::Alloc(kParentOpSize);
  ASSERT_TRUE(opt_operation.has_value());
  Operation operation = *std::move(opt_operation);

  OperationList list;
  // Empty list.
  EXPECT_TRUE(list.find(&operation) == std::nullopt);
  EXPECT_EQ(list.size(), 0u);

  list.push_back(&operation);
  EXPECT_EQ(list.size(), 1u);

  // List only has one operation.
  EXPECT_TRUE(list.prev(&operation) == std::nullopt);
  EXPECT_TRUE(list.next(&operation) == std::nullopt);

  std::optional<size_t> idx = list.find(&operation);
  EXPECT_TRUE(idx.has_value());
  EXPECT_EQ(idx.value(), 0u);

  // Delete the operation and verify it's no longer in the list.
  EXPECT_TRUE(list.erase(&operation));
  EXPECT_EQ(list.size(), 0u);

  idx = list.find(&operation);
  EXPECT_FALSE(idx.has_value());
}

TEST(OperationListTest, MultipleOperation) {
  OperationList list;
  // This is for verifying prev / next pointer values when iterating the list.
  TestOp* ops[10];

  for (size_t i = 0; i < 10; i++) {
    std::optional<Operation> opt_operation = Operation::Alloc(kParentOpSize);
    ASSERT_TRUE(opt_operation.has_value());
    Operation operation = *std::move(opt_operation);

    list.push_back(&operation);
    EXPECT_EQ(list.size(), i + 1);

    ops[i] = operation.take();
  }
  EXPECT_EQ(list.size(), 10u);

  // Verify iterating in both directions.
  auto opt_operation = list.begin();
  for (size_t i = 0; i < 10; i++) {
    EXPECT_TRUE(opt_operation.has_value());
    Operation operation = *std::move(opt_operation);

    std::optional<size_t> idx = list.find(&operation);
    EXPECT_TRUE(idx.has_value());
    EXPECT_EQ(idx.value(), i);

    auto prev = list.prev(&operation);
    if (i == 0) {
      EXPECT_FALSE(prev.has_value());
    } else {
      EXPECT_TRUE(prev.has_value());
      EXPECT_EQ(prev->operation(), ops[i - 1]);
    }

    auto next = list.next(&operation);
    if (i == 9) {
      EXPECT_FALSE(next.has_value());
    } else {
      EXPECT_TRUE(next.has_value());
      EXPECT_EQ(next->operation(), ops[i + 1]);
    }

    opt_operation = std::move(next);
  }
  EXPECT_FALSE(opt_operation.has_value());

  for (size_t i = 0; i < 10; i++) {
    auto opt_operation = list.begin();
    EXPECT_TRUE(opt_operation.has_value());
    Operation operation = *std::move(opt_operation);
    EXPECT_TRUE(list.erase(&operation));

    // Force the destructor to run.
    __UNUSED auto op = Operation(ops[i], kParentOpSize);
  }
  EXPECT_EQ(list.size(), 0u);
  EXPECT_FALSE(list.begin().has_value());
}

TEST(OperationListTest, Release) {
  OperationList list;
  TestOp* ops[10];

  for (size_t i = 0; i < 10; i++) {
    std::optional<Operation> opt_operation = Operation::Alloc(kParentOpSize);
    ASSERT_TRUE(opt_operation.has_value());
    Operation operation = *std::move(opt_operation);
    list.push_back(&operation);
    EXPECT_EQ(list.size(), i + 1);

    ops[i] = operation.take();
  }

  list.Release();
  EXPECT_EQ(list.size(), 0u);
  EXPECT_FALSE(list.begin().has_value());

  for (size_t i = 0; i < 10; i++) {
    // Force the destructor to run.
    __UNUSED auto op = Operation(ops[i], kParentOpSize);
  }
}

TEST(OperationListTest, MultipleLayer) {
  using FirstLayerOp = BorrowedOperation;
  using SecondLayerOp = Operation;

  constexpr size_t kBaseOpSize = sizeof(TestOp);
  constexpr size_t kFirstLayerOpSize = FirstLayerOp::OperationSize(kBaseOpSize);

  TestOp* ops[10];

  OperationList second_layer_list;
  for (size_t i = 0; i < 10; i++) {
    std::optional<SecondLayerOp> opt_operation = SecondLayerOp::Alloc(kFirstLayerOpSize);
    ASSERT_TRUE(opt_operation.has_value());
    Operation operation = *std::move(opt_operation);
    second_layer_list.push_back(&operation);
    ops[i] = operation.take();
  }
  EXPECT_EQ(second_layer_list.size(), 10u);

  BorrowedOperationList first_layer_list;
  // Add the operations also into the first layer list.
  for (size_t i = 0; i < 10; i++) {
    FirstLayerOp unowned(ops[i], nullptr, nullptr, kBaseOpSize, /* allow_destruct */ false);
    first_layer_list.push_back(&unowned);
  }
  EXPECT_EQ(first_layer_list.size(), 10u);

  // Remove the operations from both lists.
  for (size_t i = 0; i < 10; i++) {
    FirstLayerOp unowned(ops[i], kBaseOpSize);
    std::optional<size_t> idx = first_layer_list.find(&unowned);
    EXPECT_TRUE(idx.has_value());
    EXPECT_EQ(idx.value(), 0u);
    EXPECT_TRUE(first_layer_list.erase(&unowned));

    SecondLayerOp operation(unowned.take(), kFirstLayerOpSize);
    idx = second_layer_list.find(&operation);
    EXPECT_TRUE(idx.has_value());
    EXPECT_EQ(idx.value(), 0u);
    EXPECT_TRUE(second_layer_list.erase(&operation));
  }
  EXPECT_EQ(first_layer_list.size(), 0u);
  EXPECT_EQ(second_layer_list.size(), 0u);
}

TEST(OperationListTest, MultipleLayerWithStorage) {
  struct FirstLayerOp
      : public operation::BorrowedOperation<FirstLayerOp, TestOpTraits, CallbackTraits, char> {
    using BaseClass =
        operation::BorrowedOperation<FirstLayerOp, TestOpTraits, CallbackTraits, char>;
    using BaseClass::BaseClass;
  };

  struct SecondLayerOp : public operation::Operation<SecondLayerOp, TestOpTraits, uint64_t> {
    using BaseClass = operation::Operation<SecondLayerOp, TestOpTraits, uint64_t>;
    using BaseClass::BaseClass;
  };

  constexpr size_t kBaseOpSize = sizeof(TestOp);
  constexpr size_t kFirstLayerOpSize = FirstLayerOp::OperationSize(kBaseOpSize);

  TestOp* ops[10];

  operation::OperationList<SecondLayerOp, TestOpTraits, uint64_t> second_layer_list;
  for (size_t i = 0; i < 10; i++) {
    std::optional<SecondLayerOp> opt_operation = SecondLayerOp::Alloc(kFirstLayerOpSize);
    ASSERT_TRUE(opt_operation.has_value());
    auto operation = *std::move(opt_operation);

    *operation.private_storage() = i;
    EXPECT_EQ(*operation.private_storage(), i);
    second_layer_list.push_back(&operation);
    ops[i] = operation.take();
  }
  EXPECT_EQ(second_layer_list.size(), 10u);

  operation::BorrowedOperationList<FirstLayerOp, TestOpTraits, CallbackTraits, char>
      first_layer_list;
  // Add the operations also into the first layer list.
  for (size_t i = 0; i < 10; i++) {
    FirstLayerOp unowned(ops[i], nullptr, nullptr, kBaseOpSize, /* allow_destruct */ false);
    *unowned.private_storage() = static_cast<char>('a' + first_layer_list.size());
    first_layer_list.push_back(&unowned);
  }
  EXPECT_EQ(first_layer_list.size(), 10u);

  // Verify the first layer list node's private storage and also erase them along the way.
  size_t count = 0;
  auto opt_unowned = first_layer_list.begin();
  while (opt_unowned) {
    auto unowned = *std::move(opt_unowned);
    auto next = first_layer_list.next(&unowned);

    EXPECT_EQ(*unowned.private_storage(), static_cast<char>('a' + count));
    EXPECT_TRUE(first_layer_list.erase(&unowned));

    ++count;
    opt_unowned = std::move(next);
  }
  EXPECT_EQ(count, 10);
  EXPECT_EQ(first_layer_list.size(), 0u);

  // Verify the second layer list node's private storage and also erase them along the way.
  count = 0;
  auto opt_operation = second_layer_list.begin();
  while (opt_operation) {
    auto operation = *std::move(opt_operation);
    auto next = second_layer_list.next(&operation);

    EXPECT_EQ(*operation.private_storage(), count);
    EXPECT_TRUE(second_layer_list.erase(&operation));

    ++count;
    opt_operation = std::move(next);
  }
  EXPECT_EQ(count, 10);
  EXPECT_EQ(second_layer_list.size(), 0u);

  for (size_t i = 0; i < 10; i++) {
    // Force the destructor to run.
    __UNUSED auto op = Operation(ops[i], kParentOpSize);
  }
}

TEST(OperationListTest, MultipleLayerWithCallback) {
  struct FirstLayerOp
      : public operation::BorrowedOperation<FirstLayerOp, TestOpTraits, CallbackTraits, char> {
    using BaseClass =
        operation::BorrowedOperation<FirstLayerOp, TestOpTraits, CallbackTraits, char>;
    using BaseClass::BaseClass;
  };

  struct SecondLayerOp : public operation::Operation<SecondLayerOp, TestOpTraits, uint64_t> {
    using BaseClass = operation::Operation<SecondLayerOp, TestOpTraits, uint64_t>;
    using BaseClass::BaseClass;
  };
  constexpr size_t kBaseOpSize = sizeof(TestOp);
  constexpr size_t kFirstLayerOpSize = FirstLayerOp::OperationSize(kBaseOpSize);

  TestOp* ops[10];

  operation::OperationList<SecondLayerOp, TestOpTraits, uint64_t> second_layer_list;
  for (size_t i = 0; i < 10; i++) {
    std::optional<SecondLayerOp> opt_operation = SecondLayerOp::Alloc(kFirstLayerOpSize);
    ASSERT_TRUE(opt_operation.has_value());
    SecondLayerOp operation = *std::move(opt_operation);

    *operation.private_storage() = i;
    EXPECT_EQ(*operation.private_storage(), i);
    second_layer_list.push_back(&operation);

    ops[i] = operation.take();
  }
  EXPECT_EQ(second_layer_list.size(), 10u);

  std::atomic<size_t> num_callbacks{0};

  auto callback = [](void* ctx, zx_status_t status, TestOp* operation) {
    auto counter = static_cast<std::atomic<size_t>*>(ctx);
    ++(*counter);
  };

  TestOpCallback cb = callback;

  {
    operation::BorrowedOperationList<FirstLayerOp, TestOpTraits, CallbackTraits, char>
        first_layer_list;

    // Store the operations into the first layer list.
    for (size_t i = 0; i < 10; i++) {
      FirstLayerOp unowned(ops[i], &cb, &num_callbacks, kBaseOpSize,
                           /* allow_destruct */ false);
      first_layer_list.push_back(&unowned);
    }
    EXPECT_EQ(first_layer_list.size(), 10u);
    EXPECT_EQ(second_layer_list.size(), 10u);
  }
  // The first layer list destruction should not trigger any callbacks.
  EXPECT_EQ(num_callbacks.load(), 0u);

  second_layer_list.Release();
  EXPECT_EQ(second_layer_list.size(), 0u);

  for (int i = 0; i < 10; i++) {
    // Force the destructor to run.
    __UNUSED auto op = SecondLayerOp(ops[i], kFirstLayerOpSize);
  }
}

}  // namespace
