// 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/fidl/cpp/builder.h>
#include <lib/fidl/cpp/message.h>
#include <lib/fidl/cpp/message_builder.h>
#include <lib/fidl/llcpp/string_view.h>
#include <lib/fidl/llcpp/transaction.h>
#include <lib/sync/completion.h>
#include <limits.h>
#include <zircon/syscalls.h>

#include <thread>
#include <type_traits>

#include <fidl/test/coding/fuchsia/llcpp/fidl.h>
#include <fidl/test/coding/llcpp/fidl.h>
#include <zxtest/zxtest.h>

#include "fidl_coded_types.h"

namespace {

class Transaction : public fidl::Transaction {
 public:
  Transaction() = default;
  explicit Transaction(sync_completion_t* wait, sync_completion_t* signal)
      : wait_(wait), signal_(signal) {}

  std::unique_ptr<fidl::Transaction> TakeOwnership() override { ZX_ASSERT(false); }

  zx_status_t Reply(fidl::OutgoingMessage* message) override {
    if (wait_ && signal_) {
      sync_completion_signal(signal_);
      sync_completion_wait(wait_, ZX_TIME_INFINITE);
    }
    return ZX_OK;
  }

  void Close(zx_status_t epitaph) override {}

  ~Transaction() override = default;

 private:
  sync_completion_t* wait_;
  sync_completion_t* signal_;
};

using Completer = ::llcpp::fidl::test::coding::fuchsia::Llcpp::Interface::ActionCompleter::Sync;

// A completer being destroyed without replying (but needing one) should crash
TEST(LlcppTransaction, no_reply_asserts) {
  Transaction txn{};
  ASSERT_DEATH([&] { Completer completer(&txn); }, "no reply should crash");
}

// A completer being destroyed without replying (but needing one) should crash
TEST(LlcppTransaction, no_expected_reply_doesnt_assert) {
  Transaction txn{};
  fidl::Completer<fidl::CompleterBase>::Sync completer(&txn);
}

// A completer replying twice should crash
TEST(LlcppTransaction, double_reply_asserts) {
  Transaction txn{};
  Completer completer(&txn);
  completer.Reply(0);
  ASSERT_DEATH([&] { completer.Reply(1); }, "second reply should crash");
}

// It is allowed to reply and then close
TEST(LlcppTransaction, reply_then_close_doesnt_assert) {
  Transaction txn{};
  Completer completer(&txn);
  completer.Reply(0);
  completer.Close(ZX_ERR_INVALID_ARGS);
}

// It is not allowed to close then reply
TEST(LlcppTransaction, close_then_reply_asserts) {
  Transaction txn{};
  Completer completer(&txn);
  completer.Close(ZX_ERR_INVALID_ARGS);
  ASSERT_DEATH([&] { completer.Reply(1); }, "reply after close should crash");
}

// It is not allowed to be accessed from multiple threads simultaneously
TEST(LlcppTransaction, concurrent_access_asserts) {
  sync_completion_t signal, wait;
  Transaction txn{&signal, &wait};
  Completer completer(&txn);
  std::thread t([&] { completer.Reply(1); });
  sync_completion_wait(&wait, ZX_TIME_INFINITE);
  // TODO(fxbug.dev/54499): Hide assertion failed messages from output - they are confusing.
  ASSERT_DEATH([&] { completer.Reply(1); }, "concurrent access should crash");
  ASSERT_DEATH([&] { completer.Close(ZX_OK); }, "concurrent access should crash");
  ASSERT_DEATH([&] { completer.EnableNextDispatch(); }, "concurrent access should crash");
  ASSERT_DEATH([&] { completer.ToAsync(); }, "concurrent access should crash");
  sync_completion_signal(&signal);
  t.join();  // Don't accidentally invoke ~Completer() while `t` is still in Reply().
}

// If there is a serialization error, it does not need to be closed or replied to.
TEST(LlcppTransaction, transaction_error) {
  Transaction txn{};
  ::llcpp::fidl::test::coding::fuchsia::Llcpp::Interface::EnumActionCompleter::Sync completer(&txn);
  // We are using the fact that 2 isn't a valid enum value to cause an error.
  fidl::Result result =
      completer.Reply(static_cast<llcpp::fidl::test::coding::fuchsia::TestEnum>(2));
  ASSERT_FALSE(result.ok());
}

namespace test_async_completer_deleted_methods {

template <typename T, typename = void>
struct test : std::false_type {};
template <typename T>
struct test<T, std::void_t<decltype(std::declval<T>().EnableNextDispatch())>> : std::true_type {};

// Invoking `FooCompleter::Async::EnableNextDispatch` should be a compile-time error.
TEST(LlcppCompleter, AsyncCompleterCannotEnableNextDispatch) {
  Transaction txn{};
  Completer completer(&txn);
  static_assert(test<decltype(completer)>::value);
  static_assert(!test<decltype(completer.ToAsync())>::value);

  // Not relevant to the test, but required to neutralize the completer.
  completer.Close(ZX_OK);
}

}  // namespace test_async_completer_deleted_methods

namespace test_sync_completer_deleted_methods {

template <typename T>
T TryToMove(T t) {
  return std::move(t);
}

template <typename T, typename = void>
struct test : std::false_type {};
template <typename T>
struct test<T, std::void_t<decltype(TryToMove<T>(std::declval<T>()))>> : std::true_type {};

// Invoking move construction on `FooCompleter::Sync` should be a compile-time error.
TEST(LlcppCompleter, SyncCompleterCannotBeMoved) {
  Transaction txn{};
  Completer completer(&txn);

  // Sync one cannot be moved.
  static_assert(!test<decltype(completer)>::value);

  // Async one can be moved.
  static_assert(test<decltype(completer.ToAsync())>::value);

  // Not relevant to the test, but required to neutralize the completer.
  completer.Close(ZX_OK);
}

}  // namespace test_sync_completer_deleted_methods

}  // namespace
