/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <algorithm>
#include <cctype>
#include <charconv>
#include <regex>
#include <string>
#include <unordered_map>
#include <vector>

#include <gtest/gtest.h>

#include "Options.h"

namespace android {
namespace gtest_extras {

// The total time each test can run before timing out and being killed.
constexpr uint64_t kDefaultDeadlineThresholdMs = 90000;

// The total time each test can run before a warning is issued.
constexpr uint64_t kDefaultSlowThresholdMs = 2000;

const std::unordered_map<std::string, Options::ArgInfo> Options::kArgs = {
    {"deadline_threshold_ms", {FLAG_REQUIRES_VALUE, &Options::SetNumeric}},
    {"slow_threshold_ms", {FLAG_REQUIRES_VALUE, &Options::SetNumeric}},
    {"gtest_list_tests", {FLAG_NONE, &Options::SetBool}},
    {"gtest_filter", {FLAG_ENVIRONMENT_VARIABLE | FLAG_REQUIRES_VALUE, &Options::SetString}},
    {"gtest_flagfile", {FLAG_REQUIRES_VALUE, &Options::SetString}},
    {
        "gtest_repeat",
        {FLAG_ENVIRONMENT_VARIABLE | FLAG_REQUIRES_VALUE, &Options::SetIterations},
    },
    {"gtest_output", {FLAG_ENVIRONMENT_VARIABLE | FLAG_REQUIRES_VALUE, &Options::SetXmlFile}},
    {"gtest_print_time", {FLAG_ENVIRONMENT_VARIABLE | FLAG_OPTIONAL_VALUE, &Options::SetPrintTime}},
    {
        "gtest_also_run_disabled_tests",
        {FLAG_ENVIRONMENT_VARIABLE | FLAG_CHILD, &Options::SetBool},
    },
    {"gtest_color",
     {FLAG_ENVIRONMENT_VARIABLE | FLAG_REQUIRES_VALUE | FLAG_CHILD, &Options::SetString}},
    {"gtest_death_test_style",
     {FLAG_ENVIRONMENT_VARIABLE | FLAG_REQUIRES_VALUE | FLAG_CHILD, nullptr}},
    {"gtest_break_on_failure", {FLAG_ENVIRONMENT_VARIABLE | FLAG_INCOMPATIBLE, nullptr}},
    {"gtest_catch_exceptions", {FLAG_ENVIRONMENT_VARIABLE | FLAG_INCOMPATIBLE, nullptr}},
    {"gtest_random_seed", {FLAG_ENVIRONMENT_VARIABLE | FLAG_INCOMPATIBLE, nullptr}},
    {"gtest_shuffle", {FLAG_ENVIRONMENT_VARIABLE | FLAG_INCOMPATIBLE, nullptr}},
    {"gtest_stream_result_to", {FLAG_ENVIRONMENT_VARIABLE | FLAG_INCOMPATIBLE, nullptr}},
    {"gtest_throw_on_failure", {FLAG_ENVIRONMENT_VARIABLE | FLAG_INCOMPATIBLE, nullptr}},
    {"gtest_shard_index",
     {FLAG_ENVIRONMENT_VARIABLE | FLAG_REQUIRES_VALUE, &Options::SetNumericEnvOnly}},
    {"gtest_total_shards",
     {FLAG_ENVIRONMENT_VARIABLE | FLAG_REQUIRES_VALUE, &Options::SetNumericEnvOnly}},
    // This does nothing, only added so that passing this option does not exit.
    {"gtest_format", {FLAG_NONE, &Options::SetBool}},
};

static void PrintError(const std::string& arg, std::string msg, bool from_env) {
  if (from_env) {
    std::string variable(arg);
    std::transform(variable.begin(), variable.end(), variable.begin(),
                   [](char c) { return std::toupper(c); });
    printf("env[%s] %s\n", variable.c_str(), msg.c_str());
  } else if (arg[0] == '-') {
    printf("%s %s\n", arg.c_str(), msg.c_str());
  } else {
    printf("--%s %s\n", arg.c_str(), msg.c_str());
  }
}

template <typename IntType>
static bool GetNumeric(const std::string& arg, const std::string& value, IntType* numeric_value,
                       bool from_env) {
  auto result = std::from_chars(value.c_str(), value.c_str() + value.size(), *numeric_value, 10);
  if (result.ec == std::errc::result_out_of_range) {
    PrintError(arg, std::string("value overflows (") + value + ")", from_env);
    return false;
  } else if (result.ec == std::errc::invalid_argument || result.ptr == nullptr ||
             *result.ptr != '\0') {
    PrintError(arg, std::string("value is not formatted as a numeric value (") + value + ")",
               from_env);
    return false;
  }
  return true;
}

bool Options::SetPrintTime(const std::string&, const std::string& value, bool) {
  if (!value.empty() && strtol(value.c_str(), nullptr, 10) == 0) {
    bools_.find("gtest_print_time")->second = false;
  }
  return true;
}

bool Options::SetNumeric(const std::string& arg, const std::string& value, bool from_env) {
  uint64_t* numeric = &numerics_.find(arg)->second;
  if (!GetNumeric<uint64_t>(arg, value, numeric, from_env)) {
    return false;
  }
  if (*numeric == 0) {
    PrintError(arg, "requires a number greater than zero.", from_env);
    return false;
  }
  return true;
}

bool Options::SetNumericEnvOnly(const std::string& arg, const std::string& value, bool from_env) {
  if (!from_env) {
    PrintError(arg, "is only supported as an environment variable.", false);
    return false;
  }
  uint64_t* numeric = &numerics_.find(arg)->second;
  if (!GetNumeric<uint64_t>(arg, value, numeric, from_env)) {
    return false;
  }
  return true;
}

bool Options::SetBool(const std::string& arg, const std::string&, bool) {
  bools_.find(arg)->second = true;
  return true;
}

bool Options::SetIterations(const std::string& arg, const std::string& value, bool from_env) {
  if (!GetNumeric<int>(arg, value, &num_iterations_, from_env)) {
    return false;
  }
  return true;
}

bool Options::SetString(const std::string& arg, const std::string& value, bool) {
  strings_.find(arg)->second = value;
  return true;
}

bool Options::SetXmlFile(const std::string& arg, const std::string& value, bool from_env) {
  if (value.substr(0, 4) != "xml:") {
    PrintError(arg, "only supports an xml output file.", from_env);
    return false;
  }
  std::string xml_file(value.substr(4));
  if (xml_file.empty()) {
    PrintError(arg, "requires a file name after xml:", from_env);
    return false;
  }
  // Need an absolute file.
  if (xml_file[0] != '/') {
    char* cwd = getcwd(nullptr, 0);
    if (cwd == nullptr) {
      PrintError(arg,
                 std::string("cannot get absolute pathname, getcwd() is failing: ") +
                     strerror(errno) + '\n',
                 from_env);
      return false;
    }
    xml_file = std::string(cwd) + '/' + xml_file;
    free(cwd);
  }

  // If the output file is a directory, add the name of a file.
  if (xml_file.back() == '/') {
    xml_file += "test_details.xml";
  }
  strings_.find("xml_file")->second = xml_file;
  return true;
}

bool Options::HandleArg(const std::string& arg, const std::string& value, const ArgInfo& info,
                        bool from_env) {
  if (info.flags & FLAG_INCOMPATIBLE) {
    PrintError(arg, "is not compatible with isolation runs.", from_env);
    return false;
  }

  if (info.flags & FLAG_TAKES_VALUE) {
    if ((info.flags & FLAG_REQUIRES_VALUE) && value.empty()) {
      PrintError(arg, "requires an argument.", from_env);
      return false;
    }

    if (info.func != nullptr && !(this->*(info.func))(arg, value, from_env)) {
      return false;
    }
  } else if (!value.empty()) {
    PrintError(arg, "does not take an argument.", from_env);
    return false;
  } else if (info.func != nullptr) {
    return (this->*(info.func))(arg, value, from_env);
  }
  return true;
}

static bool ReadFileToString(const std::string& file, std::string* contents) {
  int fd = TEMP_FAILURE_RETRY(open(file.c_str(), O_RDONLY | O_CLOEXEC));
  if (fd == -1) {
    return false;
  }
  char buf[4096];
  ssize_t bytes_read;
  while ((bytes_read = TEMP_FAILURE_RETRY(read(fd, &buf, sizeof(buf)))) > 0) {
    contents->append(buf, bytes_read);
  }
  close(fd);
  return true;
}

bool Options::ProcessFlagfile(const std::string& file, std::vector<char*>* child_args) {
  std::string contents;
  if (!ReadFileToString(file, &contents)) {
    printf("Unable to read data from file %s\n", file.c_str());
    return false;
  }

  std::regex flag_regex("^\\s*(\\S.*\\S)\\s*$");
  std::regex empty_line_regex("^\\s*$");
  size_t idx = 0;
  while (idx < contents.size()) {
    size_t newline_idx = contents.find('\n', idx);
    if (newline_idx == std::string::npos) {
      newline_idx = contents.size();
    }
    std::string line(&contents[idx], newline_idx - idx);
    idx = newline_idx + 1;
    std::smatch match;
    if (std::regex_match(line, match, flag_regex)) {
      line = match[1];
    } else if (std::regex_match(line, match, empty_line_regex)) {
      // Skip lines with only whitespace.
      continue;
    }
    if (!ProcessSingle(line.c_str(), child_args, false)) {
      return false;
    }
  }
  return true;
}

bool Options::ProcessSingle(const char* arg, std::vector<char*>* child_args, bool allow_flagfile) {
  if (strncmp("--", arg, 2) != 0) {
    if (arg[0] == '-') {
      printf("Unknown argument: %s\n", arg);
      return false;
    } else {
      printf("Unexpected argument '%s'\n", arg);
      return false;
    }
  }

  // See if this is a name=value argument.
  std::string name;
  std::string value;
  const char* equal = strchr(arg, '=');
  if (equal != nullptr) {
    name = std::string(&arg[2], static_cast<size_t>(equal - arg) - 2);
    value = equal + 1;
  } else {
    name = &arg[2];
  }
  auto entry = kArgs.find(name);
  if (entry == kArgs.end()) {
    printf("Unknown argument: %s\n", arg);
    return false;
  }

  if (entry->second.flags & FLAG_CHILD) {
    child_args->push_back(strdup(arg));
  }

  if (!HandleArg(name, value, entry->second)) {
    return false;
  }

  // Special case, if gtest_flagfile is set, then we need to read the
  // file and treat each line as a flag.
  if (name == "gtest_flagfile") {
    if (!allow_flagfile) {
      printf("Argument: %s is not allowed in flag file.\n", arg);
      return false;
    }
    if (!ProcessFlagfile(value, child_args)) {
      return false;
    }
  }

  return true;
}

bool Options::Process(const std::vector<const char*>& args, std::vector<char*>* child_args) {
  // Initialize the variables.
  job_count_ = static_cast<size_t>(sysconf(_SC_NPROCESSORS_ONLN));
  num_iterations_ = ::testing::GTEST_FLAG(repeat);
  numerics_.clear();
  numerics_["deadline_threshold_ms"] = kDefaultDeadlineThresholdMs;
  numerics_["slow_threshold_ms"] = kDefaultSlowThresholdMs;
  numerics_["gtest_shard_index"] = 0;
  numerics_["gtest_total_shards"] = 0;
  strings_.clear();
  strings_["gtest_color"] = ::testing::GTEST_FLAG(color);
  strings_["xml_file"] = ::testing::GTEST_FLAG(output);
  strings_["gtest_filter"] = "";
  strings_["gtest_flagfile"] = "";
  bools_.clear();
  bools_["gtest_print_time"] = ::testing::GTEST_FLAG(print_time);
  bools_["gtest_also_run_disabled_tests"] = ::testing::GTEST_FLAG(also_run_disabled_tests);
  bools_["gtest_list_tests"] = false;

  // This does nothing, only added so that passing this option does not exit.
  bools_["gtest_format"] = true;

  // Loop through all of the possible environment variables.
  for (const auto& entry : kArgs) {
    if (entry.second.flags & FLAG_ENVIRONMENT_VARIABLE) {
      std::string variable(entry.first);
      std::transform(variable.begin(), variable.end(), variable.begin(),
                     [](char c) { return std::toupper(c); });
      char* env = getenv(variable.c_str());
      if (env == nullptr) {
        continue;
      }
      std::string value(env);
      if (!HandleArg(entry.first, value, entry.second, true)) {
        return false;
      }
    }
  }

  child_args->push_back(strdup(args[0]));

  // Assumes the first value is not an argument, so skip it.
  for (size_t i = 1; i < args.size(); i++) {
    // Special handle of -j or -jXX. This flag is not allowed to be present
    // in a --gtest_flagfile.
    if (strncmp(args[i], "-j", 2) == 0) {
      const char* value = &args[i][2];
      if (*value == '\0') {
        // Get the next argument.
        if (i == args.size() - 1) {
          printf("-j requires an argument.\n");
          return false;
        }
        i++;
        value = args[i];
      }
      if (!GetNumeric<size_t>("-j", value, &job_count_, false)) {
        return false;
      }
    } else {
      if (!ProcessSingle(args[i], child_args, true)) {
        return false;
      }
    }
  }

  return true;
}

}  // namespace gtest_extras
}  // namespace android
