// 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/fdio/spawn.h>
#include <lib/fit/defer.h>
#include <lib/zx/channel.h>
#include <lib/zx/clock.h>
#include <lib/zx/process.h>
#include <zircon/processargs.h>
#include <zircon/utc.h>

#include <string>

#include <zxtest/zxtest.h>

namespace {

const std::string kHelperFlag{"utc-procargs-helper"};
constexpr zx::duration kProcessTerminateTimeout = zx::sec(20);

// A small wrapper used to launch a process which will fetch the current clock
// from the environment which should have been set up by libc, and send back
// to us details about the clock that it sees.
class TargetProcess {
 public:
  struct ResponseMessage {
    // Note: this is not an actual handle.  It is simply the value observed by
    // the process target.  We use it to make sure that the handle is invalid
    // when it should be.
    zx_handle_t observed_utc_handle;
    zx_koid_t observed_utc_koid;
    zx_rights_t observed_utc_rights;
  };

  static void SetProgramName(const char* program_name) { program_name_ = program_name; }
  static int Main();

  TargetProcess() = default;

  // No copy or move, either via construction or assignment.
  TargetProcess(const TargetProcess&) = delete;
  TargetProcess(TargetProcess&&) = delete;
  TargetProcess& operator=(const TargetProcess&) = delete;
  TargetProcess& operator=(TargetProcess&&) = delete;

  ~TargetProcess() { Stop(); }

  void Run(zx::clock clock_to_send);
  const zx::channel& control_channel() const { return control_channel_; }

 private:
  static const char* program_name_;

  void Stop() {
    // If the target process is valid, attempt to kill it.  It should have
    // exited already, but something must have gone terribly wrong.
    if (target_process_) {
      target_process_.kill();
      target_process_.reset();
    }
    control_channel_.reset();
  }

  zx::process target_process_;
  zx::channel control_channel_;
};

const char* TargetProcess::program_name_ = nullptr;

// Run the target process, passing the clock provided (if any) and wait for it to exit.
void TargetProcess::Run(zx::clock clock_to_send) {
  auto on_failure = fit::defer([this]() { Stop(); });

  // Make sure that we have a program name and have not already started.
  ASSERT_NOT_NULL(program_name_);
  ASSERT_EQ(target_process_.get(), ZX_HANDLE_INVALID);
  ASSERT_EQ(control_channel_.get(), ZX_HANDLE_INVALID);

  // Create the channel we will use for talking to our external process.
  zx::channel remote;
  ASSERT_OK(zx::channel::create(0, &control_channel_, &remote));

  const char* args[] = {program_name_, kHelperFlag.c_str(), nullptr};
  size_t handles_to_send = clock_to_send.is_valid() ? 2 : 1;
  struct fdio_spawn_action startup_handles[] = {
      {.action = FDIO_SPAWN_ACTION_ADD_HANDLE,
       .h = {.id = PA_HND(PA_USER0, 0), .handle = remote.release()}},
      {.action = FDIO_SPAWN_ACTION_ADD_HANDLE,
       .h = {.id = PA_HND(PA_CLOCK_UTC, 0), .handle = clock_to_send.release()}}};

  // Clone everything but the UTC clock, which is being passed explicitly.
  const uint32_t spawn_flags = FDIO_SPAWN_CLONE_ALL & ~FDIO_SPAWN_CLONE_UTC_CLOCK;
  char err_msg_out[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];
  zx_status_t res =
      fdio_spawn_etc(ZX_HANDLE_INVALID, spawn_flags, program_name_, args, nullptr, handles_to_send,
                     startup_handles, target_process_.reset_and_get_address(), err_msg_out);
  ASSERT_OK(res, "%s", err_msg_out);

  // Wait for the process we spawned to exit.  We wait a finite (but very long)
  // amount of time for this to happen in the hopes that if something goes wrong
  // that we will have a chance to kill the process we spawned instead of
  // needing to hope that our test framework will be able to do so for us.
  ASSERT_OK(target_process_.wait_one(ZX_PROCESS_TERMINATED,
                                     zx::deadline_after(kProcessTerminateTimeout), nullptr));

  // OK, the process exited.  Go ahead and close the handle so that we don't
  // bother to try and kill it later on.
  target_process_.reset();

  // Things went well!  Cancel our on_failure cleanup routine.
  on_failure.cancel();
}

int TargetProcess::Main() {
  // Get a hold of the channel we will use to respond to the test harness with,
  // extract the details of the clock object (the koid and the rights), and send
  // it back to the test harness for validation.  If anything goes wrong here,
  // return the non-zero line number at which failure occurred in an attempt to
  // give an indication to the test process something to log which might be
  // helpful for someone trying to figure out where the helper process failed in
  // the case that all they have to go on are some automated test logs.
  //
  // If things go well, return 0 to indicate success.
  zx::channel response_channel(zx_take_startup_handle(PA_HND(PA_USER0, 0)));
  if (!response_channel.is_valid()) {
    return ZX_ERR_INVALID_ARGS;
  }

  // Now take a peek at our clock handle as stashed by the runtime.
  TargetProcess::ResponseMessage response{};
  response.observed_utc_handle = zx_utc_reference_get();
  zx::unowned_clock utc_clock(response.observed_utc_handle);

  if (utc_clock->is_valid()) {
    zx_info_handle_basic_t clock_info{};
    zx_status_t res = utc_clock->get_info(ZX_INFO_HANDLE_BASIC, &clock_info, sizeof(clock_info),
                                          nullptr, nullptr);

    if (res != ZX_OK) {
      return res;
    }

    response.observed_utc_koid = clock_info.koid;
    response.observed_utc_rights = clock_info.rights;
  }

  // Send a message back with the details of the clock that the runtime has
  // stashed for us.
  return response_channel.write(0, &response, sizeof(response), nullptr, 0);
}

// We will end up running three variants of the test, but the vast majority of
// the code that we are going to run is common, so we pick which variant we want
// using an enum at runtime to reduce code duplication.  Note, if there was a
// reason to, this decision could be made using templates and expanded at
// compile time instead.
enum class TransferTestFlavor {
  kNoHandleProvided,
  kReadOnlyHandleProvided,
  kReadWriteHandleProvided,
};

void TransferTestCommon(TransferTestFlavor flavor) {
  zx::clock the_clock;
  zx_info_handle_basic_t clock_info{};

  // If this test involves actually creating a clock, create it now, start it,
  // reduce its rights to the appropriate level, and stash its basic information
  // for later validation.
  if ((flavor == TransferTestFlavor::kReadOnlyHandleProvided) ||
      (flavor == TransferTestFlavor::kReadWriteHandleProvided)) {
    // Just go with a default clock for now.  We don't really care all that much
    // about the features of the clock for these tests.
    ASSERT_OK(zx::clock::create(0, nullptr, &the_clock));

    // Start the clock, just in case the environment we are sending the clock to
    // has any opinions at all as to whether or not the clock should be running.
    ASSERT_OK(the_clock.update(zx::clock::update_args().set_value(zx::time(0))));

    // Query and stash the basic info
    ASSERT_OK(the_clock.get_info(ZX_INFO_HANDLE_BASIC, &clock_info, sizeof(clock_info), nullptr,
                                 nullptr));

    // If this test involves a read-only clock, reduce the rights on our handle.
    if (flavor == TransferTestFlavor::kReadOnlyHandleProvided) {
      clock_info.rights &= ~ZX_RIGHT_WRITE;
      ASSERT_OK(the_clock.replace(clock_info.rights, &the_clock));
    }
  }

  // Now go ahead and run, passing it the clock we created (if any)
  TargetProcess target_process;
  ASSERT_NO_FATAL_FAILURE(target_process.Run(std::move(the_clock)));

  // At this point, the process should have already sent us a response in the
  // control channel and exited.  Go ahead and read the response now.
  TargetProcess::ResponseMessage response;
  ASSERT_OK(target_process.control_channel().read(0, &response, nullptr, sizeof(response), 0,
                                                  nullptr, nullptr));

  // Now just check the results based on the type of test we are running.
  switch (flavor) {
    // If this was the no-handle test, then we should just have HANDLE_INVALID
    // for the handle value, and nothing else.
    case TransferTestFlavor::kNoHandleProvided:
      EXPECT_EQ(ZX_HANDLE_INVALID, response.observed_utc_handle);
      break;

    // For either the read-only, or the read write tests, the handle should not
    // be invalid, the koid/rights should match what we sent to the process
    // exactly.  We do not expect the runtime to reduce the rights any further.
    case TransferTestFlavor::kReadOnlyHandleProvided:
    case TransferTestFlavor::kReadWriteHandleProvided:
      EXPECT_NE(ZX_HANDLE_INVALID, response.observed_utc_handle);
      EXPECT_EQ(clock_info.koid, response.observed_utc_koid);
      EXPECT_EQ(clock_info.rights, response.observed_utc_rights);
      break;

    default:
      ASSERT_TRUE(false);
      break;
  };
}

TEST(UtcProcargsTestCase, TransferNoHandle) {
  ASSERT_NO_FAILURES(TransferTestCommon(TransferTestFlavor::kNoHandleProvided));
}

TEST(UtcProcargsTestCase, TransferReadOnly) {
  ASSERT_NO_FAILURES(TransferTestCommon(TransferTestFlavor::kReadOnlyHandleProvided));
}

TEST(UtcProcargsTestCase, TransferReadWrite) {
  ASSERT_NO_FAILURES(TransferTestCommon(TransferTestFlavor::kReadWriteHandleProvided));
}

}  // namespace

int main(int argc, char** argv) {
  TargetProcess::SetProgramName(argv[0]);

  // If we were the spawned helper process, then fork off to the helper process
  // behavior instead of running the tests.
  if ((argc == 2) && !strcmp(argv[1], kHelperFlag.c_str())) {
    return TargetProcess::Main();
  }

  return RUN_ALL_TESTS(argc, argv);
}
