// 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 <lib/fidl/txn_header.h>
#include <string.h>
#include <zircon/errors.h>
#include <zircon/fidl.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>

#include <fidl/test/echo/c/fidl.h>
#include <zxtest/zxtest.h>

static int kContext = 42;
static size_t g_echo_call_count = 0u;

static zx_status_t echo(void* ctx, zx_handle_t process, zx_handle_t thread, fidl_txn_t* txn) {
  ++g_echo_call_count;
  EXPECT_EQ(&kContext, ctx, "");
  EXPECT_NE(ZX_HANDLE_INVALID, process, "");
  EXPECT_NE(ZX_HANDLE_INVALID, thread, "");
  EXPECT_NE(NULL, txn, "");
  zx_handle_close(process);
  zx_handle_close(thread);
  return ZX_OK;
}

TEST(ServerTests, dispatch_test) {
  fidl_test_echo_Echo_ops_t ops = {
      .Echo = echo,
  };

  fidl_test_echo_EchoEchoRequest request;
  memset(&request, 0, sizeof(request));
  zx_txid_t txid = 42;
  fidl_init_txn_header(&request.hdr, txid, fidl_test_echo_EchoEchoOrdinal);
  request.process = FIDL_HANDLE_PRESENT;
  request.thread = FIDL_HANDLE_PRESENT;

  zx_handle_t handles[2];
  fidl_msg_t msg = {
      .bytes = &request,
      .handles = handles,
      .num_bytes = sizeof(request),
      .num_handles = 2,
  };

  fidl_txn_t txn;
  memset(&txn, 0, sizeof(txn));

  // Success

  zx_status_t status = zx_eventpair_create(0, &handles[0], &handles[1]);
  ASSERT_EQ(ZX_OK, status, "");
  EXPECT_EQ(0u, g_echo_call_count, "");
  status = fidl_test_echo_Echo_dispatch(&kContext, &txn, &msg, &ops);
  ASSERT_EQ(ZX_OK, status, "");
  EXPECT_EQ(1u, g_echo_call_count, "");
  g_echo_call_count = 0u;

  // Bad ordinal (dispatch)

  request.hdr.ordinal = 8949;
  zx_handle_t canary0 = ZX_HANDLE_INVALID;
  status = zx_eventpair_create(0, &handles[0], &canary0);
  ASSERT_EQ(ZX_OK, status, "");

  zx_handle_t canary1 = ZX_HANDLE_INVALID;
  status = zx_eventpair_create(0, &handles[1], &canary1);
  ASSERT_EQ(ZX_OK, status, "");

  EXPECT_EQ(0u, g_echo_call_count, "");
  status = fidl_test_echo_Echo_dispatch(&kContext, &txn, &msg, &ops);
  ASSERT_EQ(ZX_ERR_NOT_SUPPORTED, status, "");
  EXPECT_EQ(0u, g_echo_call_count, "");
  g_echo_call_count = 0u;
  status = zx_object_signal_peer(canary0, 0, ZX_USER_SIGNAL_0);
  ASSERT_EQ(ZX_ERR_PEER_CLOSED, status, "");
  status = zx_object_signal_peer(canary1, 0, ZX_USER_SIGNAL_0);
  ASSERT_EQ(ZX_ERR_PEER_CLOSED, status, "");
  zx_handle_close(canary0);
  zx_handle_close(canary1);

  // Bad ordinal (try_dispatch)

  request.hdr.ordinal = 8949;
  canary0 = ZX_HANDLE_INVALID;
  status = zx_eventpair_create(0, &handles[0], &canary0);
  ASSERT_EQ(ZX_OK, status, "");

  canary1 = ZX_HANDLE_INVALID;
  status = zx_eventpair_create(0, &handles[1], &canary1);
  ASSERT_EQ(ZX_OK, status, "");

  EXPECT_EQ(0u, g_echo_call_count, "");
  status = fidl_test_echo_Echo_try_dispatch(&kContext, &txn, &msg, &ops);
  ASSERT_EQ(ZX_ERR_NOT_SUPPORTED, status, "");
  EXPECT_EQ(0u, g_echo_call_count, "");
  g_echo_call_count = 0u;
  status = zx_object_signal_peer(canary0, 0, ZX_USER_SIGNAL_0);
  ASSERT_EQ(ZX_OK, status, "");
  status = zx_object_signal_peer(canary1, 0, ZX_USER_SIGNAL_0);
  ASSERT_EQ(ZX_OK, status, "");
  zx_handle_close_many(handles, 2);
  zx_handle_close(canary0);
  zx_handle_close(canary1);
}

typedef struct my_connection {
  fidl_txn_t txn;
  size_t count;
} my_connection_t;

static zx_status_t reply_handler(fidl_txn_t* txn, const fidl_msg_t* msg) {
  my_connection_t* my_txn = (my_connection_t*)txn;
  EXPECT_EQ(sizeof(fidl_test_echo_EchoEchoResponse), msg->num_bytes, "");
  EXPECT_EQ(0u, msg->num_handles, "");

  fidl_message_header_t* hdr = (fidl_message_header_t*)msg->bytes;
  EXPECT_EQ(hdr->magic_number, kFidlWireFormatMagicNumberInitial, "");
  ++my_txn->count;
  return ZX_OK;
}

TEST(ServerTests, reply_test) {
  my_connection_t conn;
  conn.txn.reply = reply_handler;
  conn.count = 0u;

  zx_status_t status = fidl_test_echo_EchoEcho_reply(&conn.txn, ZX_OK);
  ASSERT_EQ(ZX_OK, status, "");
  EXPECT_EQ(1u, conn.count, "");
}

static zx_status_t return_async(void* ctx, zx_handle_t process, zx_handle_t thread,
                                fidl_txn_t* txn) {
  zx_handle_close(process);
  zx_handle_close(thread);
  return ZX_ERR_ASYNC;
}

TEST(ServerTests, error_test) {
  fidl_test_echo_Echo_ops_t ops = {
      .Echo = return_async,
  };

  fidl_test_echo_EchoEchoRequest request;
  memset(&request, 0, sizeof(request));
  zx_txid_t txid = 42;
  fidl_init_txn_header(&request.hdr, txid, fidl_test_echo_EchoEchoOrdinal);
  request.process = FIDL_HANDLE_PRESENT;
  request.thread = FIDL_HANDLE_PRESENT;

  zx_handle_t handles[2];
  fidl_msg_t msg = {
      .bytes = &request,
      .handles = handles,
      .num_bytes = sizeof(request),
      .num_handles = 2,
  };

  fidl_txn_t txn;
  memset(&txn, 0, sizeof(txn));

  zx_status_t status = zx_eventpair_create(0, &handles[0], &handles[1]);
  ASSERT_EQ(ZX_OK, status, "");
  status = fidl_test_echo_Echo_try_dispatch(NULL, &txn, &msg, &ops);
  ASSERT_EQ(ZX_ERR_ASYNC, status, "");
}

TEST(ServerTests, incompatible_magic_test) {
  fidl_test_echo_Echo_ops_t ops = {
      .Echo = return_async,
  };

  fidl_test_echo_EchoEchoRequest request;
  memset(&request, 0, sizeof(request));
  zx_txid_t txid = 42;
  fidl_init_txn_header(&request.hdr, txid, fidl_test_echo_EchoEchoOrdinal);
  request.hdr.magic_number = 0;
  request.process = FIDL_HANDLE_PRESENT;
  request.thread = FIDL_HANDLE_PRESENT;

  zx_handle_t handles[2];
  fidl_msg_t msg = {
      .bytes = &request,
      .handles = handles,
      .num_bytes = sizeof(request),
      .num_handles = 2,
  };

  fidl_txn_t txn;
  memset(&txn, 0, sizeof(txn));

  zx_status_t status = zx_eventpair_create(0, &handles[0], &handles[1]);
  ASSERT_EQ(ZX_OK, status, "");
  status = fidl_test_echo_Echo_try_dispatch(NULL, &txn, &msg, &ops);
  ASSERT_EQ(ZX_ERR_PROTOCOL_NOT_SUPPORTED, status, "");
}
