// 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/async/wait.h>
#include <lib/fidl-async/cpp/bind.h>
#include <zircon/fidl.h>
#include <zircon/status.h>

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

namespace test = ::llcpp::llcpptest::transitional::test;

namespace {

class Server : public test::TransitionMethods::Interface {
 public:
  void ImplementedMethod(ImplementedMethodCompleter::Sync txn) override {
    // Reply call to maintain an open connection.
    txn.Reply(fidl::StringView("test reply"));
  }

  void Bind(zx::channel server, async::Loop* loop) {
    zx_status_t bind_status = fidl::Bind(loop->dispatcher(), std::move(server), this);
    EXPECT_EQ(bind_status, ZX_OK);
  }
};

class TransitionalTest : public ::testing::Test {
 protected:
  virtual void SetUp() {
    loop_ = std::make_unique<async::Loop>(&kAsyncLoopConfigAttachToCurrentThread);
    ASSERT_EQ(loop_->StartThread("test_llcpp_transitional_server"), ZX_OK);
    ASSERT_EQ(zx::channel::create(0, &client_end_, &server_end_), ZX_OK);
    server_ = std::make_unique<Server>();
    server_->Bind(std::move(server_end_), loop_.get());
  }

  virtual void TearDown() {
    loop_->Quit();
    loop_->JoinThreads();
  }

  test::TransitionMethods::SyncClient TakeClient() {
    EXPECT_TRUE(client_end_.is_valid());
    return test::TransitionMethods::SyncClient(std::move(client_end_));
  }

 private:
  std::unique_ptr<async::Loop> loop_;
  std::unique_ptr<Server> server_;
  zx::channel client_end_;
  zx::channel server_end_;
};

// The implemented call should succeed.
TEST_F(TransitionalTest, CallImplementedMethod) {
  auto client = TakeClient();
  auto result = client.ImplementedMethod();
  EXPECT_TRUE(result.ok());
  EXPECT_EQ(result.error(), nullptr) << result.error();
  ASSERT_EQ(result.status(), ZX_OK) << zx_status_get_string(result.status());
}

// The unimplemented transitional call should error with not supported in an
// epitaph. However, epitaphs are currently not supported (fxb/35445) so the
// server closes the connection on an unsupported call. This results in a peer
// connection closed error instead.
TEST_F(TransitionalTest, CallUnimplementedMethod) {
  auto client = TakeClient();
  auto result = client.UnimplementedMethod();
  EXPECT_FALSE(result.ok());
  EXPECT_EQ(result.error(), nullptr) << result.error();
  ASSERT_EQ(result.status(), ZX_ERR_PEER_CLOSED) << zx_status_get_string(result.status());
}

}  // namespace
