// 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 <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <algorithm>
#include <filesystem>
#include <iterator>
#include <sstream>
#include <string>

#include <zxtest/zxtest.h>

#include "lib/fdio/fd.h"
#include "lib/fdio/fdio.h"
#include "lib/fdio/io.h"
#include "lib/fdio/spawn.h"
#include "lib/zx/channel.h"
#include "lib/zx/object.h"
#include "lib/zx/process.h"
#include "lib/zx/socket.h"
#include "zircon/limits.h"
#include "zircon/processargs.h"
#include "zircon/syscalls/object.h"
#include "zircon/syscalls/policy.h"
#include "zircon/types.h"

static constexpr char kDash[] = "/pkg/bin/sh";
static constexpr const char* kDashArgv[] = {kDash, nullptr};

static void join(const zx::process& process) {
  ASSERT_OK(process.wait_one(ZX_TASK_TERMINATED, zx::time::infinite(), nullptr));
  zx_info_process_t proc_info{};
  ASSERT_OK(process.get_info(ZX_INFO_PROCESS, &proc_info, sizeof(proc_info), nullptr, nullptr));
  ASSERT_EQ(0, proc_info.return_code);
}

TEST(DashTests, dash_ls_test) {
  zx_status_t status;
  zx::process process;
  zx::socket sstdout, sstdin;
  int stdout, stdin;

  status = fdio_pipe_half(&stdout, sstdout.reset_and_get_address());
  ASSERT_GE(status, ZX_OK);
  status = fdio_pipe_half(&stdin, sstdin.reset_and_get_address());
  ASSERT_GE(status, ZX_OK);

  fdio_spawn_action_t actions[3];
  actions[0].action = FDIO_SPAWN_ACTION_CLONE_FD;
  actions[0].fd.local_fd = 2;
  actions[0].fd.target_fd = 2;
  actions[1].action = FDIO_SPAWN_ACTION_TRANSFER_FD;
  actions[1].fd.local_fd = stdout;
  actions[1].fd.target_fd = 1;
  actions[2].action = FDIO_SPAWN_ACTION_TRANSFER_FD;
  actions[2].fd.local_fd = stdin;
  actions[2].fd.target_fd = 0;

  status = fdio_spawn_etc(
      ZX_HANDLE_INVALID,
      FDIO_SPAWN_CLONE_JOB | FDIO_SPAWN_CLONE_NAMESPACE | FDIO_SPAWN_DEFAULT_LDSVC, kDash,
      kDashArgv, nullptr, 3, actions, process.reset_and_get_address(), nullptr);

  ASSERT_EQ(ZX_OK, status);

  // Note: the PATH=; here forces the call to reach the builtin.
  std::string ls("PATH=; ls /\n");
  ASSERT_EQ(ZX_OK, sstdin.write(0, ls.data(), ls.length(), nullptr));
  sstdin.reset();

  join(process);

  std::string buf(4096, 0);
  size_t actual;
  sstdout.read(0, buf.data(), buf.length(), &actual);
  buf.resize(actual);

  // We don't really care to be hard-coupled to ls output format yet, but we
  // want one line per non-dot dirent.
  std::istringstream output(std::string(buf.begin(), buf.end()));
  int lines = 0;
  for (std::string line; std::getline(output, line);) {
    auto pos = line.rfind(" ");
    if (pos == std::string::npos) {
      continue;
    }
    line = line.substr(pos + 1);
    if (line == "." || line.size() == 0) {
      continue;
    }
    lines++;
  }

  // Check we have something vaguely meaningful
  EXPECT_GT(lines, 1);

  int expected = 0;
  for (__attribute__((unused)) auto& _ : std::filesystem::directory_iterator{"/"}) {
    expected++;
  }

  ASSERT_EQ(lines, expected);
}
