// Copyright 2022 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 <lib/fit/defer.h>

#include <cerrno>

#include <fbl/unique_fd.h>
#include <gtest/gtest.h>

#include "piped-command.h"
#include "test-tool-process.h"

#ifndef __Fuchsia__
#include <sys/wait.h>
#endif

namespace {

constexpr const char* kTestChild = "zxdump-test-child";

// TestToolProcess uses ToolPath implicitly, but PipedCommand does not.
std::string TestChildPath() { return zxdump::testing::ToolPath(kTestChild); }

#ifdef __Fuchsia__

bool NoChildren() { return true; }

bool IsProcess(const zx::process& process) { return process.is_valid(); }

void WaitFor(zx::process process, int& status) {
  ASSERT_TRUE(process);
  zx_signals_t signals = 0;
  ASSERT_EQ(process.wait_one(ZX_PROCESS_TERMINATED, zx::time::infinite(), &signals), ZX_OK);
  ASSERT_TRUE(signals & ZX_PROCESS_TERMINATED);
  zx_info_process_t info;
  ASSERT_EQ(process.get_info(ZX_INFO_PROCESS, &info, sizeof(info), nullptr, nullptr), ZX_OK);
  status = static_cast<int>(info.return_code);
}

#else

bool NoChildren() { return waitpid(-1, nullptr, WNOHANG) < 0 && errno == ECHILD; }

bool IsProcess(int pid) { return pid > 0; }

void WaitFor(int pid, int& status) {
  ASSERT_GT(pid, 0);
  ASSERT_EQ(waitpid(pid, &status, 0), pid) << "waitpid: " << pid << ": " << strerror(errno);
  status = WIFEXITED(status) ? WEXITSTATUS(status) : -WTERMSIG(status);
}

#endif

TEST(ZxdumpTests, PipedCommandStart) {
  ASSERT_TRUE(NoChildren());
  {
    zxdump::PipedCommand child;
    auto result = child.Start(TestChildPath(), {"-x", "0"});
    ASSERT_TRUE(result.is_ok()) << result.error_value();
  }
  // The destructor waited for the child to die.
  ASSERT_TRUE(NoChildren());
}

TEST(ZxdumpTests, PipedCommandProcessOwnership) {
  decltype(zxdump::PipedCommand().process()) process;
  {
    zxdump::PipedCommand child;
    auto result = child.Start(TestChildPath(), {"-x", "42"});
    ASSERT_TRUE(result.is_ok()) << result.error_value();
    ASSERT_TRUE(IsProcess(child.process()));
    process = std::move(child).process();
    ASSERT_FALSE(IsProcess(child.process()));
  }
  ASSERT_TRUE(IsProcess(process));
  int status;
  ASSERT_NO_FATAL_FAILURE(WaitFor(std::move(process), status));
  EXPECT_EQ(status, 42);
}

TEST(ZxdumpTests, PipedCommandRedirect) {
  // TestToolProcess uses PipedCommand::Redirect under the hood and
  // takes care of pushing to its stdin and pulling from its stdout.
  constexpr std::string_view kStdinContents = "stdin contents";
  zxdump::testing::TestToolProcess child;
  ASSERT_NO_FATAL_FAILURE(child.Start(kTestChild, {"-c", "-", "-x", "0"}));
  ASSERT_NO_FATAL_FAILURE(child.CollectStdout());
  ASSERT_NO_FATAL_FAILURE(child.CollectStderr());
  ASSERT_NO_FATAL_FAILURE(child.SendStdin(std::string{kStdinContents}));
  int status;
  ASSERT_NO_FATAL_FAILURE(child.Finish(status));
  EXPECT_EQ(status, 0);
  EXPECT_EQ(child.collected_stdout(), kStdinContents);
  EXPECT_EQ(child.collected_stderr(), "");
}

TEST(ZxdumpTests, TestToolProcessInputFile) {
  constexpr std::string_view kFileContents = "file contents";
  std::string in_file_name;
  {
    zxdump::testing::TestToolProcess child;
    auto& in_file = child.MakeFile("input");
    in_file_name = in_file.name();
    EXPECT_NE(in_file_name.find("input"), std::string::npos);
    {
      fbl::unique_fd in_fd = in_file.CreateInput();
      ASSERT_TRUE(in_fd) << strerror(errno);
      FILE* f = fdopen(in_fd.release(), "w");
      auto cleanup_f = fit::defer([f]() {
        if (f) {
          fclose(f);
        }
      });
      ASSERT_TRUE(f) << strerror(errno);
      fwrite(kFileContents.data(), kFileContents.size(), 1, f);
      ASSERT_FALSE(ferror(f));
    }
    ASSERT_NO_FATAL_FAILURE(child.Start(kTestChild, {"-c", in_file_name, "-x", "0"}));
    ASSERT_NO_FATAL_FAILURE(child.CollectStdout());
    ASSERT_NO_FATAL_FAILURE(child.CollectStderr());
    int status;
    ASSERT_NO_FATAL_FAILURE(child.Finish(status));
    EXPECT_EQ(status, 0);
    EXPECT_EQ(child.collected_stdout(), kFileContents);
    EXPECT_EQ(child.collected_stderr(), "");
  }
  // Should have been cleaned up on destruction.
  EXPECT_FALSE(fbl::unique_fd{open(in_file_name.c_str(), O_RDONLY)});
  EXPECT_EQ(errno, ENOENT);
}

TEST(ZxdumpTests, TestToolProcessOutputFile) {
  constexpr std::string_view kFileContents = "file contents";
  zxdump::testing::TestToolProcess child;
  auto& out_file = child.MakeFile("output");
  const std::string out_file_name = out_file.name();
  EXPECT_NE(out_file_name.find("output"), std::string::npos);
  ASSERT_NO_FATAL_FAILURE(child.Start(kTestChild, {"-o", out_file_name, "-x", "0"}));
  ASSERT_NO_FATAL_FAILURE(child.CollectStdout());
  ASSERT_NO_FATAL_FAILURE(child.CollectStderr());
  ASSERT_NO_FATAL_FAILURE(child.SendStdin(std::string{kFileContents}));
  int status;
  ASSERT_NO_FATAL_FAILURE(child.Finish(status));
  EXPECT_EQ(status, 0);
  EXPECT_EQ(child.collected_stdout(), "");
  EXPECT_EQ(child.collected_stderr(), "");
  EXPECT_EQ(out_file.OutputContents(), kFileContents);
}

}  // namespace
