// Copyright 2018 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 "src/ledger/bin/lock/lock.h"

#include <lib/fit/function.h>

#include "gtest/gtest.h"
#include "src/ledger/lib/coroutine/coroutine_impl.h"

namespace lock {
namespace {
size_t Fact(size_t n) {
  if (n == 0) {
    return 1;
  }
  return Fact(n - 1) * n;
}

void UseStack() { EXPECT_EQ(120u, Fact(5)); }

TEST(Lock, OneLock) {
  coroutine::CoroutineServiceImpl coroutine_service;
  callback::OperationSerializer serializer;

  fit::function<void(size_t)> callback;
  auto callable = [&callback](fit::function<void(size_t)> called_callback) {
    callback = std::move(called_callback);
  };

  size_t received_value = 0;
  size_t other_value = 0;
  coroutine_service.StartCoroutine([&serializer, callable, &received_value](
                                       coroutine::CoroutineHandler* handler) {
    std::unique_ptr<Lock> lock;
    EXPECT_EQ(coroutine::ContinuationStatus::OK,
              AcquireLock(handler, &serializer, &lock));
    UseStack();
    size_t value;
    EXPECT_EQ(coroutine::ContinuationStatus::OK,
              SyncCall(handler, callable, &value));
    UseStack();
    received_value = value;
  });

  EXPECT_TRUE(callback);
  EXPECT_EQ(0u, received_value);
  EXPECT_EQ(0u, other_value);

  serializer.Serialize<>([&other_value] { other_value = 1u; },
                         [](fit::closure closure) { closure(); });

  EXPECT_EQ(0u, other_value);
  callback(1);

  EXPECT_EQ(1u, received_value);
  EXPECT_EQ(1u, other_value);
}

TEST(Lock, ManyLocks) {
  constexpr size_t nb_routines = 10;
  coroutine::CoroutineServiceImpl coroutine_service;
  callback::OperationSerializer serializer;

  std::queue<fit::function<void(size_t)>> callbacks;

  std::vector<size_t> received_values;
  for (size_t i = 0; i < nb_routines; i++) {
    auto callable = [&callbacks](fit::function<void(size_t)> called_callback) {
      callbacks.push(std::move(called_callback));
    };
    coroutine_service.StartCoroutine([&serializer, callable, &received_values](
                                         coroutine::CoroutineHandler* handler) {
      std::unique_ptr<Lock> lock;
      EXPECT_EQ(coroutine::ContinuationStatus::OK,
                AcquireLock(handler, &serializer, &lock));
      UseStack();
      size_t value;
      EXPECT_EQ(coroutine::ContinuationStatus::OK,
                SyncCall(handler, callable, &value));
      UseStack();
      received_values.push_back(value);
    });
  }

  for (size_t i = 0; i < nb_routines; i++) {
    EXPECT_EQ(1u, callbacks.size());
    EXPECT_EQ(i, received_values.size());
    callbacks.front()(i);
    callbacks.pop();
    EXPECT_EQ(i, *received_values.rbegin());
  }
  EXPECT_EQ(nb_routines, received_values.size());
}

TEST(Lock, Interrupted) {
  callback::OperationSerializer serializer;
  coroutine::CoroutineHandler* handler_ptr = nullptr;

  fit::function<void()> callback;
  auto callable = [&callback](fit::function<void()> called_callback) {
    callback = std::move(called_callback);
  };

  serializer.Serialize<>([] {}, callable);

  bool executed = false;
  {
    coroutine::CoroutineServiceImpl coroutine_service;
    coroutine_service.StartCoroutine([&serializer, &executed, &handler_ptr](
                                         coroutine::CoroutineHandler* handler) {
      handler_ptr = handler;
      std::unique_ptr<Lock> lock;
      // We are interrupted.
      EXPECT_EQ(coroutine::ContinuationStatus::INTERRUPTED,
                AcquireLock(handler, &serializer, &lock));
      executed = true;
      return;
    });

    EXPECT_TRUE(callback);
    EXPECT_FALSE(executed);
  }

  EXPECT_TRUE(executed);

  callback();

  callback = nullptr;

  serializer.Serialize<>([] {}, callable);
  EXPECT_TRUE(callback);
}

}  // namespace
}  // namespace lock
