// 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/internal.h>
#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_info_t handles[2] = {
      {
          .handle = ZX_HANDLE_INVALID,
          .type = ZX_OBJ_TYPE_EVENTPAIR,
          .rights = ZX_RIGHT_SAME_RIGHTS,
      },
      {
          .handle = ZX_HANDLE_INVALID,
          .type = ZX_OBJ_TYPE_EVENTPAIR,
          .rights = ZX_RIGHT_SAME_RIGHTS,
      },
  };
  fidl_incoming_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].handle, &handles[1].handle);
  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].handle, &canary0);
  ASSERT_EQ(ZX_OK, status, "");

  zx_handle_t canary1 = ZX_HANDLE_INVALID;
  status = zx_eventpair_create(0, &handles[1].handle, &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].handle, &canary0);
  ASSERT_EQ(ZX_OK, status, "");

  canary1 = ZX_HANDLE_INVALID;
  status = zx_eventpair_create(0, &handles[1].handle, &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, "");
  FidlHandleInfoCloseMany(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_outgoing_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_info_t handles[2] = {
      {
          .handle = ZX_HANDLE_INVALID,
          .type = ZX_OBJ_TYPE_EVENTPAIR,
          .rights = ZX_RIGHT_SAME_RIGHTS,
      },
      {
          .handle = ZX_HANDLE_INVALID,
          .type = ZX_OBJ_TYPE_EVENTPAIR,
          .rights = ZX_RIGHT_SAME_RIGHTS,
      },
  };
  fidl_incoming_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].handle, &handles[1].handle);
  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_info_t handles[2] = {
      {
          .handle = ZX_HANDLE_INVALID,
          .type = ZX_OBJ_TYPE_EVENTPAIR,
          .rights = ZX_RIGHT_SAME_RIGHTS,
      },
      {
          .handle = ZX_HANDLE_INVALID,
          .type = ZX_OBJ_TYPE_EVENTPAIR,
          .rights = ZX_RIGHT_SAME_RIGHTS,
      },
  };
  fidl_incoming_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].handle, &handles[1].handle);
  ASSERT_EQ(ZX_OK, status, "");
  status = fidl_test_echo_Echo_try_dispatch(NULL, &txn, &msg, &ops);
  ASSERT_EQ(ZX_ERR_PROTOCOL_NOT_SUPPORTED, status, "");
}
