// 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 <gtest/gtest.h>
#include <src/lib/fxl/arraysize.h>
#include <src/lib/fxl/logging.h>
#include <lib/zx/channel.h>
#include <lib/zx/time.h>
#include <zircon/processargs.h>

#include "jobs.h"
#include "processes.h"
#include "test_helper.h"
#include "test_helper_fixture.h"
#include "util.h"

namespace debugger_utils {
namespace {

const char* const kHelloArgv[] = { kTestHelperPath, "hello" };
const char* const kWaitPeerClosedArgv[] = {
    kTestHelperPath, "wait-peer-closed"
};

void WaitChannelReadable(const zx::channel& channel) {
  zx_signals_t pending;
  ASSERT_EQ(channel.wait_one(ZX_CHANNEL_READABLE, zx::time::infinite(),
                             &pending), ZX_OK);
}

void ReadUint64Packet(const zx::channel& channel, uint64_t expected_value) {
  uint64_t packet;
  uint32_t packet_size;
  ASSERT_EQ(channel.read(0, &packet, nullptr, sizeof(packet), 0,
                         &packet_size, nullptr), ZX_OK);
  EXPECT_EQ(packet_size, sizeof(packet));
  EXPECT_EQ(packet, expected_value);
}

TEST_F(TestWithHelper, GetProcessThreads) {
  zx::job parent_job = GetDefaultJob();
  zx::job child_job;

  constexpr size_t kNumExtraThreads = 4;
  static const char* const argv[] = {
    kTestHelperPath,
    "start-n-threads",
    "4",
    nullptr
  };

  // Don't request additional space for new threads. We want to test there
  // being new threads and there being no space for them.
  constexpr size_t kNoExtraThreads = 0;

  ASSERT_EQ(zx::job::create(parent_job, 0, &child_job), ZX_OK);
  ASSERT_EQ(RunHelperProgram(child_job, argv), ZX_OK);

  // Wait until all the helper's threads are running.
  WaitChannelReadable(channel());
  ReadUint64Packet(channel(), kUint64MagicPacketValue);

  std::vector<zx_koid_t> threads;
  size_t num_available_threads = 0;

  size_t try_count = 1;
  size_t num_initial_threads = 1;
  EXPECT_EQ(TryGetProcessThreadKoidsForTesting(
              process(), try_count, num_initial_threads, kNoExtraThreads,
              &threads, &num_available_threads),
            ZX_OK);

  // We only requested space for one new thread so that's all we get.
  EXPECT_EQ(threads.size(), 1u);
  // The main thread and one for each additional thread;
  size_t expected_num_threads = 1 + kNumExtraThreads;
  EXPECT_EQ(expected_num_threads, num_available_threads);

  // Try a second time, this time requesting space for all threads.
  num_initial_threads = num_available_threads;
  EXPECT_EQ(TryGetProcessThreadKoidsForTesting(
              process(), try_count, num_initial_threads, kNoExtraThreads,
              &threads, &num_available_threads),
            ZX_OK);
  EXPECT_EQ(expected_num_threads, threads.size());
  EXPECT_EQ(expected_num_threads, num_available_threads);

  // Try a third time, this time asking for two iterations.
  // The first iteration won't get them all but the second will.
  try_count = 2;
  num_initial_threads = 1;
  threads.clear();
  EXPECT_EQ(TryGetProcessThreadKoidsForTesting(
              process(), try_count, num_initial_threads, kNoExtraThreads,
              &threads, &num_available_threads),
            ZX_OK);
  EXPECT_EQ(expected_num_threads, threads.size());
  EXPECT_EQ(expected_num_threads, num_available_threads);

  // And again for a fourth time, this time using the main entry point.
  try_count = 2;
  threads.clear();
  EXPECT_EQ(GetProcessThreadKoids(process(), try_count, kNoExtraThreads,
                                  &threads, &num_available_threads),
            ZX_OK);
  EXPECT_EQ(expected_num_threads, threads.size());
  EXPECT_EQ(expected_num_threads, num_available_threads);

  // Test a non-successful return.
  zx::process process2;
  zx_status_t status =
      process().duplicate(ZX_DEFAULT_PROCESS_RIGHTS &~ ZX_RIGHT_ENUMERATE,
                          &process2);
  EXPECT_EQ(status, ZX_OK);
  try_count = 1;
  threads.clear();
  EXPECT_EQ(GetProcessThreadKoids(process2, try_count, kNoExtraThreads,
                                  &threads, &num_available_threads),
            ZX_ERR_ACCESS_DENIED);
  EXPECT_EQ(threads.size(), 0u);
  process2.reset();
}

TEST(Processes, Argv) {
  std::unique_ptr<process::ProcessBuilder> builder;
  Argv argv = BuildArgv(kHelloArgv, arraysize(kHelloArgv));
  ASSERT_EQ(CreateProcessBuilder(GetDefaultJob(), kTestHelperPath, argv,
                                 sys::ServiceDirectory::CreateFromNamespace(),
                                 &builder), ZX_OK);
  builder->CloneAll();
  ASSERT_EQ(builder->Prepare(nullptr), ZX_OK);
  EXPECT_TRUE(builder->data().process.is_valid());
  EXPECT_TRUE(builder->data().root_vmar.is_valid());
  EXPECT_GT(builder->data().stack, 0u);
  EXPECT_GT(builder->data().entry, 0u);
  EXPECT_GT(builder->data().vdso_base, 0u);
  EXPECT_GT(builder->data().base, 0u);

  zx::process process;
  EXPECT_EQ(builder->Start(&process), ZX_OK);
  zx_signals_t observed;
  EXPECT_EQ(process.wait_one(ZX_PROCESS_TERMINATED, zx::time::infinite(),
                             &observed), ZX_OK);
  int rc;
  EXPECT_EQ(GetProcessReturnCode(process.get(), &rc), ZX_OK);
  EXPECT_EQ(rc, 0);
}

// We don't need to test all the ProcessBuilder API, but it's useful to
// test a few things we use.

TEST(Processes, PassHandle) {
  std::unique_ptr<process::ProcessBuilder> builder;
  Argv argv = BuildArgv(kWaitPeerClosedArgv, arraysize(kWaitPeerClosedArgv));
  ASSERT_EQ(CreateProcessBuilder(GetDefaultJob(), kTestHelperPath, argv,
                                 sys::ServiceDirectory::CreateFromNamespace(),
                                 &builder), ZX_OK);
  builder->CloneAll();

  zx::channel our_channel, their_channel;
  ASSERT_EQ(zx::channel::create(0, &our_channel, &their_channel), ZX_OK);
  builder->AddHandle(PA_HND(PA_USER0, 0), std::move(their_channel));

  ASSERT_EQ(builder->Prepare(nullptr), ZX_OK);

  zx::process process;
  EXPECT_EQ(builder->Start(&process), ZX_OK);

  zx_signals_t pending;
  ASSERT_EQ(our_channel.wait_one(ZX_CHANNEL_READABLE, zx::time::infinite(),
                                 &pending), ZX_OK);

  zx::thread thread;
  uint32_t actual_bytes, actual_handles;
  ASSERT_EQ(our_channel.read(0u, nullptr, thread.reset_and_get_address(),
                             0u, 1u, &actual_bytes, &actual_handles), ZX_OK);
  EXPECT_EQ(actual_bytes, 0u);
  EXPECT_EQ(actual_handles, 1u);

  // At this point the inferior is waiting for us to close the channel.
  our_channel.reset();

  EXPECT_EQ(process.wait_one(ZX_PROCESS_TERMINATED, zx::time::infinite(),
                             &pending), ZX_OK);
  int rc;
  EXPECT_EQ(GetProcessReturnCode(process.get(), &rc), ZX_OK);
  EXPECT_EQ(rc, 0);
}

}  // namespace
}  // namespace debugger_utils
