// 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.

#ifndef SRC_LIB_ZXDUMP_TEST_TOOL_PROCESS_H_
#define SRC_LIB_ZXDUMP_TEST_TOOL_PROCESS_H_

#ifdef __Fuchsia__
#include <lib/zx/job.h>
#include <lib/zx/process.h>
#include <lib/zx/resource.h>
#endif

#include <list>
#include <string>
#include <string_view>
#include <thread>
#include <vector>

#include <fbl/unique_fd.h>

namespace zxdump {

// Forward declaration.
class PipedCommand;

namespace testing {

// This manages a command-line tool process to be run in a sandbox (on Fuchsia)
// or from the build directory (on other hosts) with specified input and output
// files and fully captured stdin/stdout/stderr.
class TestToolProcess {
 public:
  class File {
   public:
    static constexpr std::string_view kZstdSuffix = ".zst";

    File() = default;
    File(const File&) = delete;
    File(File&&) = default;

    ~File();

    const std::string& tmp_path() const { return owner_->tmp_path(); }

    // Return the name of the file as seen by the tool run by Start.
    // This is used in composing the arguments to pass to Start.
    std::string name() const { return owner_->FilePathForTool(*this); }

    // Create the file so it can be written and used as input to the tool.
    // This is used before Start, with name() used to compose the arguments.
    fbl::unique_fd CreateInput();

    // Same, but fills the file with the given contents.
    void CreateInput(std::string_view text);

    // Read the file after it's been written by the tool.
    // This is used  after Finish.
    fbl::unique_fd OpenOutput();

    // Uses OpenOutput to read the whole file.
    std::string OutputContents();

    // Don't expect this file to be created.
    File NoFile();

    // This immediately takes the existing file already written and runs
    // the zstd tool to compress it into a file of the same name + ".zst".
    File& ZstdCompress() const;

    // This immediately takes the existing file ending in ".zst" and uses
    // the zstd tool to decompress it into a file of the same name - ".zst".
    File& ZstdDecompress() const;

   private:
    TestToolProcess* owner_ = nullptr;
    friend TestToolProcess;

    std::string name_;
  };

  TestToolProcess();
  TestToolProcess(const TestToolProcess&) = delete;
  TestToolProcess(TestToolProcess&&) = default;

  ~TestToolProcess();

  // This creates a new isolated tmp directory.
  void Init();

  // This uses an existing tmp directory shared with another TestToolProcess.
  void Init(std::string_view tmp_path);

  // Return a file name that can be passed to the tool via its Start arguments.
  // The file name will include the given name string for debugging purposes,
  // but will be unique among all MakeFileName calls on this TestToolProcess.
  // It will always end with the precise suffix given, if any.  Whether these
  // are input files the test code writes for the tool to read, or output files
  // the tool writes and the test code checks afterwards, they will be cleaned
  // up when the TestToolProcess object is destroyed.
  File& MakeFile(std::string_view name, std::string_view suffix = "");

  // Return the name to access the file in this test program.
  std::string FilePathForRunner(const File& file) const;

  // Return the name to access the file in the child tool program.
  std::string FilePathForTool(const File& file) const;

  // Start the tool running.  This throws gtest assertions for problems.  The
  // tool name is "gcore" or the like, and is found in the appropriate place.
  void Start(const std::string& tool, const std::vector<std::string>& args);

  // Wait for the tool to finish and yield what it passed to exit().  This uses
  // a negative synthetic exit code if the tool process crashed and throws
  // gtest assertions for unexpected problems aside from the process dying.
  void Finish(int& exit_status);

  // These give separate pipe ends to write to the tool's stdin or read from
  // its stdout or stderr.  After Start, these can be reset to close the pipe
  // so the tool under test sees EOF or EPIPE.  Before Start, these can be set
  // to redirect the tool to use another fd; then Start will not make a pipe.
  fbl::unique_fd& tool_stdin() { return tool_stdin_; }
  fbl::unique_fd& tool_stdout() { return tool_stdout_; }
  fbl::unique_fd& tool_stderr() { return tool_stderr_; }

  // This spawns a worker thread to feed the contents into the tool's stdin.
  // It resets tool_stdin() and moves ownership of the pipe end to the worker.
  void SendStdin(std::string contents);

  // These spawn worker threads that take ownership of the tool_stdin() or
  // tool_stdout() pipe and collect everything written into memory until Finish
  // returns.  Then collected_stdout() and collected_stderr() return them.
  void CollectStdout();
  void CollectStderr();

  std::string collected_stdout();
  std::string collected_stderr();

  const std::string& tmp_path() const { return tmp_path_; }

#ifdef __Fuchsia__
  void set_job(zx::unowned_job job) { job_ = job; }

  void set_resource(zx::unowned_resource resource) { resource_ = std::move(resource); }
#endif

 private:
  class SandboxLoop;

  std::string FilePathForRunner(const std::string& name) const;

  void SandboxCommand(PipedCommand& command);

  std::string tmp_path_;
  bool clear_tmp_ = false;
  std::list<File> files_;
  std::string collected_stdout_, collected_stderr_;
  std::thread stdin_thread_, stdout_thread_, stderr_thread_;
  fbl::unique_fd tool_stdin_, tool_stdout_, tool_stderr_;
#ifdef __Fuchsia__
  zx::process process_;
  zx::unowned_job job_ = zx::job::default_job();
  zx::unowned_resource resource_;
  std::unique_ptr<SandboxLoop> sandbox_loop_;
#else
  int process_ = -1;
#endif
};

std::string ToolPath(std::string tool);

}  // namespace testing
}  // namespace zxdump

#endif  // SRC_LIB_ZXDUMP_TEST_TOOL_PROCESS_H_
