// 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 "runtests-utils-test-utils.h"

#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>

#include <string_view>

#include <fbl/string.h>
#include <fbl/string_buffer.h>
#include <fbl/unique_fd.h>
#include <fbl/vector.h>
#include <runtests-utils/runtests-utils.h>
#include <zxtest/zxtest.h>

namespace runtests {

///////////////////////////////////////////////////////////////////////////////
// HELPER CLASSES
///////////////////////////////////////////////////////////////////////////////

fbl::String packaged_script_dir() {
  fbl::String test_root_dir(getenv("TEST_ROOT_DIR"));
  fbl::String runtests_utils_test_data_dir(
      JoinPath(test_root_dir, "test/sys/runtests-utils-testdata"));
  return runtests_utils_test_data_dir;
}

PackagedScriptFile::PackagedScriptFile(const std::string_view path) {
  fbl::String script_dir = packaged_script_dir();
  path_ = JoinPath(script_dir, path);

  // Open the file to be sure that it exists.
  const int fd = open(path_.data(), O_RDONLY);
  ZX_ASSERT_MSG(-1 != fd, "%s", strerror(errno));
  ZX_ASSERT_MSG(-1 != close(fd), "%s", strerror(errno));
}

PackagedScriptFile::~PackagedScriptFile() = default;

std::string_view PackagedScriptFile::path() const { return path_; }

ScopedStubFile::ScopedStubFile(const std::string_view path) : path_(path) {
  const int fd = open(path_.data(), O_CREAT | O_WRONLY, S_IRWXU);
  ZX_ASSERT_MSG(-1 != fd, "%s", strerror(errno));
  ZX_ASSERT_MSG(-1 != close(fd), "%s", strerror(errno));
}

ScopedStubFile::~ScopedStubFile() { remove(path_.data()); }

ScopedTestFile::ScopedTestFile(const std::string_view path, const std::string_view file)
    : path_(path) {
  fbl::unique_fd input_fd{open(file.data(), O_RDONLY)};
  ZX_ASSERT_MSG(input_fd, "%s", strerror(errno));

  fbl::unique_fd output_fd{open(path_.data(), O_CREAT | O_WRONLY, S_IRWXU)};
  ZX_ASSERT_MSG(output_fd, "%s", strerror(errno));

  constexpr size_t kBufSize = 1024;

  char buf[kBufSize];
  ssize_t n;
  while ((n = read(input_fd.get(), buf, kBufSize)) > 0) {
    ZX_ASSERT_MSG(write(output_fd.get(), buf, n) == n, "write failed: %s", strerror(errno));
  }
  ZX_ASSERT_MSG(n != -1, "read failed: %s", strerror(errno));
}

ScopedTestFile::~ScopedTestFile() { remove(path_.data()); }

std::string_view ScopedTestFile::path() const { return path_; }

int ScopedTestDir::num_test_dirs_created_ = 0;

///////////////////////////////////////////////////////////////////////////////
// FILE I/O HELPERS
///////////////////////////////////////////////////////////////////////////////

// Returns the number of files or subdirectories in a given directory.
int NumEntriesInDir(const char* dir_path) {
  struct dirent* entry;
  int num_entries = 0;
  DIR* dp;

  if (!(dp = opendir(dir_path))) {
    // dir_path actually points to a file. Return -1 by convention.
    return -1;
  }
  while ((entry = readdir(dp))) {
    // Skip "." and "..".
    if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) {
      continue;
    }
    ++num_entries;
  }
  closedir(dp);
  return num_entries;
}

// Computes the relative path within |output_dir| of the output file of the
// test at |test_path|, setting |output_file_rel_path| as its value if
// successful.
// Returns true iff successful.
bool GetOutputFileRelPath(std::string_view output_dir, std::string_view test_path,
                          fbl::String* output_file_rel_path) {
  if (output_file_rel_path == nullptr) {
    printf("FAILURE: |output_file_rel_path| was null.");
    return false;
  }
  fbl::String dir_of_test_output = JoinPath(output_dir, test_path);
  DIR* dp = opendir(dir_of_test_output.c_str());
  if (dp == nullptr) {
    printf("FAILURE: could not open directory %s: %s\n", dir_of_test_output.c_str(),
           strerror(errno));
    return false;
  }
  struct dirent* entry;
  int num_entries = 0;
  fbl::String output_file_name;
  while ((entry = readdir(dp))) {
    // Skip "." and "..".
    if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) {
      continue;
    }
    if (entry->d_type != DT_REG) {
      continue;
    }
    output_file_name = fbl::String(entry->d_name);
    ++num_entries;
  }
  closedir(dp);
  *output_file_rel_path = JoinPath(test_path, output_file_name);
  if (num_entries != 1) {
    printf(
        "FAILURE: there are %d entries in %s. There should only be a "
        "single output file\n",
        num_entries, dir_of_test_output.c_str());
  }
  return num_entries == 1;
}

namespace {

constexpr char kTmp[] = "/tmp";

// This ensures that ScopedTestDir, ScopedTestFile, and ScopedStubFile, which we
// make heavy use of in these tests, are indeed scoped and tear down without
// error.
TEST(TestHelpers, ScopedDirsAndFilesAreIndeedScoped) {
  const int baseEntries = NumEntriesInDir(kTmp);

  {
    ScopedTestDir dir(kTmp);
    EXPECT_EQ(1 + baseEntries, NumEntriesInDir(kTmp));

    EXPECT_EQ(0, NumEntriesInDir(dir.path()));
    {
      fbl::String file_name1 = JoinPath(dir.path(), "a.sh");
      PackagedScriptFile source_file_1("succeed.sh");
      ScopedTestFile file1(file_name1, source_file_1.path());

      EXPECT_EQ(1, NumEntriesInDir(dir.path()));
      {
        fbl::String file_name2 = JoinPath(dir.path(), "b.sh");
        ScopedStubFile file2(file_name2);
        EXPECT_EQ(2, NumEntriesInDir(dir.path()));
      }
      EXPECT_EQ(1, NumEntriesInDir(dir.path()));
    }
    EXPECT_EQ(0, NumEntriesInDir(dir.path()));
  }

  EXPECT_EQ(baseEntries, NumEntriesInDir(kTmp));

  {
    ScopedTestDir dir1(kTmp);
    ScopedTestDir dir2(kTmp);
    ScopedTestDir dir3(kTmp);
    EXPECT_EQ(3 + baseEntries, NumEntriesInDir(kTmp));
  }

  EXPECT_EQ(baseEntries, NumEntriesInDir(kTmp));
}

}  // namespace
}  // namespace runtests
