// 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/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/fidl/llcpp/server.h>
#include <lib/fidl/llcpp/server_end.h>
#include <lib/zx/object.h>
#include <zircon/errors.h>
#include <zircon/status.h>
#include <zircon/syscalls/object.h>

#include <gtest/gtest.h>
#include <llcpptest/protocol/test/llcpp/fidl.h>

namespace llcpp_test = ::llcpp::llcpptest::protocol::test;

TEST(ServerEnd, Trivial) {
  fidl::ServerEnd<llcpp_test::Frobinator> server_end;
  EXPECT_FALSE(server_end.is_valid());
}

TEST(ServerEnd, Control) {
  zx::channel h1, h2;
  ASSERT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));
  zx_handle_t saved1 = h1.get();

  // Test initializing with channel.
  fidl::ServerEnd<llcpp_test::Frobinator> server_end(std::move(h1));
  EXPECT_TRUE(server_end.is_valid());
  EXPECT_EQ(saved1, server_end.channel().get());

  // Test move semantics.
  fidl::ServerEnd<llcpp_test::Frobinator> server_end_2 = std::move(server_end);
  EXPECT_FALSE(server_end.is_valid());
  EXPECT_TRUE(server_end_2.is_valid());
  EXPECT_EQ(saved1, server_end_2.channel().get());

  h1 = server_end_2.TakeChannel();
  EXPECT_EQ(saved1, h1.get());
  EXPECT_FALSE(server_end_2.is_valid());

  zx_handle_t saved2 = h2.get();
  server_end.set_channel(std::move(h2));
  EXPECT_TRUE(server_end.is_valid());
  EXPECT_EQ(saved2, server_end.channel().get());

  // Test RAII channel management.
  server_end = {};
  EXPECT_FALSE(server_end.is_valid());
  EXPECT_EQ(ZX_ERR_PEER_CLOSED, h1.write(0, "a", 1, nullptr, 0));
}

TEST(ServerEnd, Close) {
  async::Loop loop(&kAsyncLoopConfigNoAttachToCurrentThread);
  zx::channel h1, h2;
  ASSERT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));

  fidl::UnbindInfo recorded_unbind_info;
  fidl::Client<llcpp_test::Frobinator> client(
      std::move(h1), loop.dispatcher(), [&recorded_unbind_info](fidl::UnbindInfo unbind_info) {
        recorded_unbind_info = unbind_info;
      });

  fidl::ServerEnd<llcpp_test::Frobinator> server_end(std::move(h2));
  EXPECT_TRUE(server_end.is_valid());

  constexpr zx_status_t kSysError = ZX_ERR_INVALID_ARGS;
  EXPECT_EQ(ZX_OK, server_end.Close(kSysError));
  EXPECT_FALSE(server_end.is_valid());

  loop.RunUntilIdle();
  EXPECT_EQ(fidl::UnbindInfo::Reason::kPeerClosed, recorded_unbind_info.reason);
  EXPECT_EQ(kSysError, recorded_unbind_info.status);
}

TEST(ServerEnd, CloseTwice) {
  zx::channel h1, h2;
  ASSERT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));
  fidl::ServerEnd<llcpp_test::Frobinator> server_end(std::move(h2));
  EXPECT_EQ(ZX_OK, server_end.Close(ZX_OK));

  ASSERT_DEATH(server_end.Close(ZX_OK), "Cannot close an invalid ServerEnd.");
}
