// Copyright 2016 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 <errno.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <zircon/process.h>
#include <zircon/processargs.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/object.h>

#include <elfload/elfload.h>
#include <test-utils/test-utils.h>
#include <unittest/unittest.h>

#include "threads_impl.h"
#include "util.h"

static bool stdio_pipe_test(void) {
  BEGIN_TEST;

  int fds[2];
  ASSERT_EQ(pipe(fds), 0, "pipe creation failed");

  ASSERT_GT(write(fds[1], "hello", 5), 0, "pipe write failed");

  char buffer[5];
  ASSERT_GT(read(fds[0], buffer, 5), 0, "pipe read failed");

  ASSERT_EQ(strncmp(buffer, "hello", 5), 0, "Incorrect buffer read from pipe");

  ASSERT_EQ(lseek(fds[0], 0, SEEK_SET), -1, "lseek should have failed");
  ASSERT_EQ(errno, ESPIPE, "lseek error should have been pipe-related");

  ASSERT_EQ(close(fds[0]), 0, "");
  ASSERT_EQ(close(fds[1]), 0, "");

  END_TEST;
}

static zx_handle_t handle_from_fd(int fd) {
  zx_handle_t handle = ZX_HANDLE_INVALID;
  zx_status_t status = fdio_fd_transfer(fd, &handle);
  if (status != ZX_OK)
    tu_fatal("handle from fd", status);
  return handle;
}

static bool stdio_advanced_pipe_test(void) {
  BEGIN_TEST;

  // TODO(kulakowski): Consider another helper process
  const char* file = "/boot/bin/lsusb";

  zx_handle_t fdio_job = zx_job_default();
  ASSERT_NE(fdio_job, ZX_HANDLE_INVALID, "no fdio job object");

  zx_handle_t job_copy = ZX_HANDLE_INVALID;
  ASSERT_EQ(zx_handle_duplicate(fdio_job, ZX_RIGHT_SAME_RIGHTS, &job_copy), ZX_OK,
            "zx_handle_duplicate failed");

  // stdio pipe fds [ours, theirs]
  int stdin_fds[2];
  int stdout_fds[2];
  int stderr_fds[2];

  ASSERT_EQ(stdio_pipe(stdin_fds, true), 0, "stdin pipe creation failed");
  ASSERT_EQ(stdio_pipe(stdout_fds, false), 0, "stdout pipe creation failed");
  ASSERT_EQ(stdio_pipe(stderr_fds, false), 0, "stderr pipe creation failed");

  zx_handle_t handles[] = {
    handle_from_fd(stdin_fds[1]),
    handle_from_fd(stdout_fds[1]),
    handle_from_fd(stderr_fds[1]),
  };
  uint32_t handle_ids[] = {
    PA_HND(PA_FD, 0),
    PA_HND(PA_FD, 1),
    PA_HND(PA_FD, 2),
  };

  // Start the process
  zx_handle_t p = tu_launch_process(job_copy, "pipe_stdio_test", 1, &file, 0, NULL,
                                    countof(handles), handles, handle_ids);
  ASSERT_NE(p, ZX_HANDLE_INVALID, "process handle != 0");

  // Read the stdio
  uint8_t* out = NULL;
  size_t out_size = 0;
  uint8_t* err = NULL;
  size_t err_size = 0;

  ASSERT_GE(read_to_end(stdout_fds[0], &out, &out_size), 0, "reading stdout failed");
  ASSERT_GE(read_to_end(stderr_fds[0], &err, &err_size), 0, "reading stderr failed");

  ASSERT_EQ(strncmp((char*)out, "ID   ", 5), 0, "Got wrong stdout");
  ASSERT_EQ(err_size, (size_t)0, "Got wrong stderr");

  free(out);
  free(err);

  close(stdin_fds[0]);
  close(stdout_fds[0]);
  close(stderr_fds[0]);

  // Wait for the process to finish
  zx_status_t r;

  r = zx_object_wait_one(p, ZX_PROCESS_TERMINATED, ZX_TIME_INFINITE, NULL);
  ASSERT_EQ(r, ZX_OK, "zx_object_wait_one failed");

  // read the return code
  zx_info_process_t proc_info;
  size_t actual = 0;
  zx_object_get_info(p, ZX_INFO_PROCESS, &proc_info, sizeof(proc_info), &actual, NULL);
  ASSERT_EQ(actual, (size_t)1, "Must get one and only one process info");
  ASSERT_EQ(proc_info.return_code, 0, "lsusb must return 0");

  zx_handle_close(p);

  END_TEST;
}

static bool stdio_handle_to_tid_mapping(void) {
  BEGIN_TEST;

  // Basic expectations.
  ASSERT_EQ(__thread_handle_to_filelock_tid(0b0011), 0, "");
  ASSERT_EQ(__thread_handle_to_filelock_tid(0b0111), 1, "");
  ASSERT_EQ(__thread_handle_to_filelock_tid(0x123f), 0x48f, "");
  ASSERT_EQ(__thread_handle_to_filelock_tid(0x80000000), 0x20000000, "");
  ASSERT_EQ(__thread_handle_to_filelock_tid(0xffffffff), 0x3fffffff, "");
  ASSERT_EQ(__thread_handle_to_filelock_tid(0xffffffff), 0x3fffffff, "");

  zx_handle_t last_h0 = 0;
  for (zx_handle_t h0 = ZX_HANDLE_FIXED_BITS_MASK; h0 > last_h0;
       last_h0 = h0, h0 += ZX_HANDLE_FIXED_BITS_MASK + 1) {
    // Ensure no handles are ever mapped to negative.
    ASSERT_GE(__thread_handle_to_filelock_tid(h0), 0, "pid_t must be >= 0");
  }

  END_TEST;
}

typedef struct ThreadData {
  FILE* f;
  size_t index;
} ThreadData;

static void* thread_func_do_some_printing(void* arg) {
  ThreadData* data = (ThreadData*)arg;
  for (int i = 0; i < 100; ++i) {
    fprintf(data->f, "this is message %d from thread %zu\n", i, data->index);
  }
  return NULL;
}

// This is a crash regression test, multithreaded access to FILE* was racy and
// could crash. If this test is "flaky", this has regressed. See ZX-4278.
static bool stdio_race_on_file_access(void) {
  BEGIN_TEST;

  zx_time_t start_time = zx_clock_get_monotonic();
  while (zx_clock_get_monotonic() - start_time < ZX_SEC(5)) {
    FILE* f = tmpfile();
    ASSERT_NONNULL(f, "tmpfile failed");

    pthread_t threads[100];
    ThreadData thread_data[countof(threads)];

    for (size_t i = 0; i < countof(threads); ++i) {
      ThreadData* data = &thread_data[i];
      data->f = f;
      data->index = i;

      int err = pthread_create(&threads[i], NULL, thread_func_do_some_printing, data);
      ASSERT_EQ(err, 0, "pthread_create");
    }

    for (size_t i = 0; i < countof(threads); ++i) {
      int err = pthread_join(threads[i], NULL);
      ASSERT_EQ(err, 0, "pthread_join");
    }

    fclose(f);
  }

  END_TEST;
}

BEGIN_TEST_CASE(stdio_tests)
RUN_TEST(stdio_pipe_test);
RUN_TEST(stdio_advanced_pipe_test);
RUN_TEST(stdio_handle_to_tid_mapping);
RUN_TEST(stdio_race_on_file_access);
END_TEST_CASE(stdio_tests)
