// Copyright 2021 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 "zircon/system/ulib/profile/config.h"

#include <fcntl.h>
#include <lib/fitx/result.h>
#include <lib/syslog/global.h>
#include <lib/zx/profile.h>
#include <lib/zx/time.h>
#include <zircon/syscalls/profile.h>

#include <algorithm>
#include <limits>
#include <sstream>
#include <string>
#include <unordered_map>

#include <fbl/unique_fd.h>
#include <rapidjson/document.h>
#include <rapidjson/error/en.h>
#include <re2/re2.h>
#include <src/lib/files/directory.h>
#include <src/lib/files/file.h>

using zircon_profile::Profile;
using zircon_profile::ProfileScope;

namespace {

constexpr char kConfigFileExtension[] = ".profiles";

std::string ToString(const zx_profile_info_t& info) {
  std::ostringstream stream;

  stream << "{ ";

  if (info.flags & ZX_PROFILE_INFO_FLAG_PRIORITY) {
    stream << "\"priority\": " << info.priority << ", ";
  }
  if (info.flags & ZX_PROFILE_INFO_FLAG_DEADLINE) {
    stream << "\"capacity\": " << info.deadline_params.capacity
           << ", \"deadline\": " << info.deadline_params.relative_deadline
           << ", \"period\": " << info.deadline_params.period << ", ";
  }
  if (info.flags & ZX_PROFILE_INFO_FLAG_CPU_MASK) {
    stream << "\"affinity\": " << info.cpu_affinity_mask.mask[0] << " (0x" << std::hex
           << info.cpu_affinity_mask.mask[0] << "), " << std::dec;
  }

  stream << "}";
  return stream.str();
}

std::string ToString(ProfileScope scope) {
  switch (scope) {
    case ProfileScope::Bringup:
      return "bringup";
    case ProfileScope::Core:
      return "core";
    case ProfileScope::Product:
      return "product";
    default:
      return "none";
  }
}
// Proxies an iterator over the members of the given value node. As of this
// writing, the version of rapidjson in third_party does not support range-based
// for loops. This adapter provides the missing functionality.
struct IterateMembers {
  explicit IterateMembers(const rapidjson::Value& value)
      : begin_iterator{value.MemberBegin()}, end_iterator{value.MemberEnd()} {}

  auto begin() { return begin_iterator; }
  auto end() { return end_iterator; }

  rapidjson::Value::ConstMemberIterator begin_iterator;
  rapidjson::Value::ConstMemberIterator end_iterator;
};

// Proxies an iterator over the values of the given array node. Provides missing
// functionality similar to the iterator above.
struct IterateValues {
  explicit IterateValues(const rapidjson::Value& value)
      : begin_iterator{value.Begin()}, end_iterator{value.End()} {}

  auto begin() { return begin_iterator; }
  auto end() { return end_iterator; }

  rapidjson::Value::ConstValueIterator begin_iterator;
  rapidjson::Value::ConstValueIterator end_iterator;
};

// Utility to build a fitx::result<std::string, ?> in the error state using stream operators.
//
// Example:
//
//   return Error() << "Failed to open file " << filename << "!";
//
class Error {
 public:
  Error() = default;
  explicit Error(const std::string& initial) : stream_{initial} {}

  // Forwards the stream operator argument to the underlying ostream.
  template <typename T>
  Error& operator<<(const T& value) {
    stream_ << value;
    return *this;
  }

  // Implicit conversion to fitx::result<std::string, ?> in the error state with accumulated string
  // as the error value.
  template <typename... Vs>
  operator fitx::result<std::string, Vs...>() const {
    return fitx::error(stream_.str());
  }

  operator fitx::error<std::string>() const { return fitx::error(stream_.str()); }

 private:
  std::ostringstream stream_;
};

fitx::result<std::string, zx::duration> ParseDurationString(const std::string& duration) {
  // Match one or more digits, optionally followed by time units ms, us, or ns.
  static const re2::RE2 kReDuration{"^(\\d+)(ms|us|ns)?$"};

  int64_t scalar;
  std::string units;
  const bool matched = re2::RE2::PartialMatch(duration, kReDuration, &scalar, &units);
  if (!matched) {
    return Error() << "String \"" << duration << "\" is not a valid duration!";
  }

  if (units.empty() || units == "ns") {
    return fitx::ok(zx::nsec(scalar));
  }
  if (units == "ms") {
    return fitx::ok(zx::msec(scalar));
  }
  if (units == "us") {
    return fitx::ok(zx::usec(scalar));
  }
  return Error() << "String duration \"" << duration << "\" has unrecognized units \"" << units
                 << "\"!";
}

fitx::result<std::string, zx::duration> ParseDuration(const rapidjson::Value& object) {
  if (object.IsInt()) {
    return fitx::ok(zx::nsec(object.GetInt()));
  }
  if (object.IsString()) {
    return ParseDurationString(object.GetString());
  }
  return fitx::error("Duration must be an integer or duration string!");
}

struct TextPosition {
  int32_t line;
  int32_t column;
};

TextPosition GetLineAndColumnForOffset(const std::string& input, size_t offset) {
  if (offset == 0) {
    // Errors at position 0 are assumed to be related to the whole file.
    return {.line = 0, .column = 0};
  }

  TextPosition position = {.line = 1, .column = 1};
  for (size_t i = 0; i < input.size() && i < offset; i++) {
    if (input[i] == '\n') {
      position.line += 1;
      position.column = 1;
    } else {
      position.column += 1;
    }
  }

  return position;
}

std::string GetErrorMessage(const rapidjson::Document& document, const std::string& file_data) {
  const auto [line, column] = GetLineAndColumnForOffset(file_data, document.GetErrorOffset());
  std::ostringstream stream;
  stream << line << ":" << column << ": " << GetParseError_En(document.GetParseError());
  return stream.str();
}

template <typename... Context>
auto GetMember(const char* name, const rapidjson::Value& object, Context&&... context)
    -> fitx::result<std::string, decltype(std::cref(object[name]))> {
  if (!object.IsObject()) {
    return (Error() << ... << std::forward<Context>(context)) << " must be a JSON object!";
  }
  if (!object.HasMember(name)) {
    return (Error() << ... << std::forward<Context>(context))
           << " must have a \"" << name << "\" member!";
  }
  return fitx::ok(std::cref(object[name]));
}

template <typename... Context>
fitx::result<std::string, int> GetInt(const char* name, const rapidjson::Value& object,
                                      Context&&... context) {
  auto result = GetMember(name, object, std::forward<Context>(context)...);
  if (result.is_error()) {
    return result.take_error();
  }
  if (!result->get().IsInt()) {
    return (Error() << ... << std::forward<Context>(context))
           << " member \"" << name << "\" must be an integer!";
  }
  return fitx::ok(result->get().GetInt());
}

template <typename... Context>
fitx::result<std::string, const char*> GetString(const char* name, const rapidjson::Value& object,
                                                 Context&&... context) {
  auto result = GetMember(name, object, std::forward<Context>(context)...);
  if (result.is_error()) {
    return result.take_error();
  }
  if (!result->get().IsString()) {
    return (Error() << ... << std::forward<Context>(context))
           << " member \"" << name << "\" must be a string!";
  }
  return fitx::ok(result->get().GetString());
}

template <typename... Context>
auto GetArray(const char* name, const rapidjson::Value& object, Context&&... context) {
  auto result = GetMember(name, object, std::forward<Context>(context)...);
  if (result.is_ok() && !result->get().IsArray()) {
    return (Error() << ... << std::forward<Context>(context))
           << " member \"" << name << "\" must be an array!";
  }
  return result;
}

template <typename... Context>
auto GetObject(const char* name, const rapidjson::Value& object, Context&&... context) {
  auto result = GetMember(name, object, std::forward<Context>(context)...);
  if (result.is_ok() && !result->get().IsObject()) {
    return (Error() << ... << std::forward<Context>(context))
           << " member \"" << name << "\" must be a JSON object!";
  }
  return result;
}

template <typename... Context>
fitx::result<std::string, unsigned int> GetUint(const char* name, const rapidjson::Value& object,
                                                Context&&... context) {
  auto result = GetMember(name, object, std::forward<Context>(context)...);
  if (result.is_error()) {
    return result.take_error();
  }
  if (!result->get().IsUint()) {
    return (Error() << ... << std::forward<Context>(context)).rdbuf()
           << " member \"" << name << "\" must be an unsigned integer!";
  }
  return fitx::ok(result->get().GetUint());
}

void ParseProfiles(const std::string& filename, const rapidjson::Document& document,
                   zircon_profile::ProfileMap* profiles) {
  if (!document.IsObject()) {
    FX_LOG(WARNING, "ProfileProvider", "The profile config document must be a JSON object!");
    return;
  }

  if (!document.HasMember("profiles")) {
    return;
  }
  const rapidjson::Value& profile_member = document["profiles"];

  ProfileScope scope = ProfileScope::None;
  if (document.HasMember("scope")) {
    auto result = GetString("scope", document);
    if (result.is_ok()) {
      if (!strcmp(*result, "bringup")) {
        scope = ProfileScope::Bringup;
      } else if (!strcmp(*result, "core")) {
        scope = ProfileScope::Core;
      } else if (!strcmp(*result, "product")) {
        scope = ProfileScope::Product;
      } else {
        FX_LOGF(WARNING, "ProfileProvider", "%s: Invalid role scope \"%s\", defaulting to none!",
                filename.c_str(), *result);
      }
    }
  } else {
    FX_LOGF(WARNING, "ProfileProvider", "%s: Missing role scope, defaulting to none!",
            filename.c_str());
  }

  for (const auto& profile : IterateMembers(profile_member)) {
    const char* profile_name = profile.name.GetString();
    if (!profile.value.IsObject()) {
      FX_LOGF(WARNING, "ProfileProvider", "%s: Profile \"%s\" value must be a JSON object!",
              filename.c_str(), profile_name);
      continue;
    }

    const bool has_priority = profile.value.HasMember("priority");
    const bool has_capacity = profile.value.HasMember("capacity");
    const bool has_deadline = profile.value.HasMember("deadline");
    const bool has_period = profile.value.HasMember("period");
    const bool has_affinity = profile.value.HasMember("affinity");

    const bool has_complete_deadline = has_capacity && has_deadline && has_period;
    const bool has_some_deadline = has_capacity || has_deadline || has_period;

    zx_profile_info_t info{};
    if (has_priority && !has_some_deadline) {
      auto result = GetInt("priority", profile.value, "Profile ", profile_name);
      if (result.is_ok()) {
        info.flags = ZX_PROFILE_INFO_FLAG_PRIORITY;
        info.priority =
            std::clamp<int32_t>(result.value(), ZX_PRIORITY_LOWEST, ZX_PRIORITY_HIGHEST);
      } else {
        FX_LOGF(WARNING, "ProfileProvider", "\"%s\": %s", profile_name,
                result.error_value().c_str());
        continue;
      }
    } else if (!has_priority && has_complete_deadline) {
      auto capacity_result = ParseDuration(profile.value["capacity"]);
      if (capacity_result.is_error()) {
        FX_LOGF(WARNING, "ProfileProvider", "\"%s\": %s", profile_name,
                capacity_result.error_value().c_str());
        continue;
      }
      auto deadline_result = ParseDuration(profile.value["deadline"]);
      if (deadline_result.is_error()) {
        FX_LOGF(WARNING, "ProfileProvider", "\"%s\": %s", profile_name,
                deadline_result.error_value().c_str());
        continue;
      }
      auto period_result = ParseDuration(profile.value["period"]);
      if (period_result.is_error()) {
        FX_LOGF(WARNING, "ProfileProvider", "\"%s\": %s", profile_name,
                period_result.error_value().c_str());
        continue;
      }
      info.flags = ZX_PROFILE_INFO_FLAG_DEADLINE;
      info.deadline_params = zx_sched_deadline_params_t{.capacity = capacity_result->get(),
                                                        .relative_deadline = deadline_result->get(),
                                                        .period = period_result->get()};
    } else if (has_priority && has_some_deadline) {
      FX_LOGF(WARNING, "ProfileProvider",
              "%s: \"%s\": Priority and deadline parameters are mutually exclusive!",
              filename.c_str(), profile_name);
      continue;
    } else if (!has_priority && !has_complete_deadline && has_some_deadline) {
      FX_LOGF(
          WARNING, "ProfileProvider",
          "%s: \"%s\": Deadline profiles must specify \"capacity\", \"deadline\", and \"period\"!",
          filename.c_str(), profile_name);
      continue;
    }

    if (has_affinity) {
      const auto& affinity_member = profile.value["affinity"];
      const bool is_uint = affinity_member.IsUint64();
      const bool is_array = affinity_member.IsArray();

      info.flags |= ZX_PROFILE_INFO_FLAG_CPU_MASK;

      if (is_uint) {
        static_assert(std::numeric_limits<uint64_t>::digits <= ZX_CPU_SET_BITS_PER_WORD);
        info.cpu_affinity_mask.mask[0] = affinity_member.GetUint64();
      } else if (is_array) {
        size_t element_count = 0;
        bool failed = false;

        for (const auto& value : IterateValues(affinity_member)) {
          if (!value.IsUint()) {
            FX_LOGF(WARNING, "ProfileProvider",
                    "%s: \"%s\": Array element %zu of profile member \"affinity\" must be an "
                    "unsigned integer!",
                    filename.c_str(), profile_name, element_count);
            failed = true;
            break;
          }

          element_count++;
          const size_t cpu_number = value.GetUint();

          if (cpu_number >= ZX_CPU_SET_MAX_CPUS) {
            FX_LOGF(
                WARNING, "ProfileProvider",
                "%s: \"%s\": Profile member \"affinity\" must be an integer in the range [0, %u)!",
                filename.c_str(), profile_name, ZX_CPU_SET_MAX_CPUS);
            failed = true;
            break;
          }

          info.cpu_affinity_mask.mask[cpu_number / ZX_CPU_SET_BITS_PER_WORD] |=
              uint64_t{1} << (cpu_number % ZX_CPU_SET_BITS_PER_WORD);
        }
        if (failed) {
          continue;
        }
      } else {
        FX_LOGF(
            WARNING, "ProfileProvider",
            "%s: \"%s\": Profile member \"affinity\" must be a uint64 or an array of CPU indices!",
            filename.c_str(), profile_name);
        continue;
      }
    }  // if (has_affinity)

    if (info.flags == 0) {
      FX_LOGF(WARNING, "ProfileProvider", "%s: Ignoring empty profile \"%s\".", filename.c_str(),
              profile_name);
      continue;
    }

    const auto [iter, added] = profiles->emplace(profile_name, Profile{scope, info});
    if (!added) {
      if (iter->second.scope >= scope) {
        FX_LOGF(WARNING, "ProfileProvider", "%s: Profile \"%s\"already exists at %s scope.",
                filename.c_str(), profile_name, ToString(scope).c_str());
      } else if (iter->second.scope < scope) {
        FX_LOGF(INFO, "ProfileProvider", "%s: Profile \"%s\" overridden at %s scope.",
                filename.c_str(), profile_name, ToString(scope).c_str());
        iter->second = Profile{scope, info};
      }
    }
  }  // for (const auto& profile : IterateMembers(document))
}

}  // anonymous namespace

namespace zircon_profile {

fitx::result<std::string, ProfileMap> LoadConfigs(const std::string& config_path) {
  fbl::unique_fd dir_fd(openat(AT_FDCWD, config_path.c_str(), O_RDONLY | O_DIRECTORY));
  if (!dir_fd.is_valid()) {
    // A non-existent directory is not an error.
    FX_LOGF(WARNING, "ProfileProvider", "Failed to open config dir: %s", config_path.c_str());
    return fitx::ok(ProfileMap{});
  }

  std::vector<std::string> dir_entries;
  if (!files::ReadDirContentsAt(dir_fd.get(), ".", &dir_entries)) {
    return Error() << "Could not read directory contents from path " << config_path.c_str()
                   << " error " << strerror(errno);
  }

  const auto filename_predicate = [](const std::string& filename) {
    const auto pos = filename.rfind(kConfigFileExtension);
    return pos != std::string::npos && pos == (filename.size() - std::strlen(kConfigFileExtension));
  };

  ProfileMap profiles;
  for (const auto& entry : dir_entries) {
    if (!files::IsFileAt(dir_fd.get(), entry) || !filename_predicate(entry)) {
      continue;
    }

    FX_LOGF(INFO, "ProfileProvider", "Loading config: %s", entry.c_str());

    std::string data;
    if (!files::ReadFileToStringAt(dir_fd.get(), entry, &data)) {
      FX_LOGF(WARNING, "ProfileProvider", "Failed to read file: %s", entry.c_str());
      continue;
    }

    rapidjson::Document document;
    const auto kFlags = rapidjson::kParseCommentsFlag | rapidjson::kParseTrailingCommasFlag |
                        rapidjson::kParseIterativeFlag;
    document.Parse<kFlags>(data);

    if (document.HasParseError()) {
      FX_LOGF(WARNING, "ProfileProvider", "%s:%s", entry.c_str(),
              GetErrorMessage(document, data).c_str());
      continue;
    }

    ParseProfiles(entry, document, &profiles);
  }

  FX_LOGF(INFO, "ProfileProvider", "Loaded profiles:");
  for (const auto& [key, value] : profiles) {
    FX_LOGF(INFO, "ProfileProvider", "  %-32s %-10s %s", key.c_str(), ToString(value.scope).c_str(),
            ToString(value.info).c_str());
  }

  return fitx::ok(std::move(profiles));
}

}  // namespace zircon_profile
