// 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/fit/result.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/zx/profile.h>
#include <lib/zx/time.h>
#include <zircon/assert.h>
#include <zircon/syscalls/profile.h>

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

#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 fuchsia_scheduler::Parameter;
using fuchsia_scheduler::ParameterValue;
using zircon_profile::Profile;
using zircon_profile::ProfileScope;
using zircon_profile::Role;

namespace {

constexpr char kConfigFileExtension[] = ".profiles";

std::string ToString(const std::vector<Parameter> params) {
  std::ostringstream stream;
  stream << "{ ";
  for (auto param : params) {
    stream << param.key() << ": ";
    switch (param.value().Which()) {
      case ParameterValue::Tag::kIntValue:
        stream << std::to_string(param.value().int_value().value());
        break;
      case ParameterValue::Tag::kFloatValue:
        stream << std::to_string(param.value().float_value().value());
        break;
      case ParameterValue::Tag::kStringValue:
        stream << param.value().string_value().value();
        break;
      default:
        FX_SLOG(WARNING, "invalid output parameter format");
    }
    stream << ", ";
  }
  stream << " }";
  return stream.str();
}

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 fit::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 fit::result<std::string, ?> in the error state with accumulated string
  // as the error value.
  template <typename... Vs>
  operator fit::result<std::string, Vs...>() const {
    return fit::error(stream_.str());
  }

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

 private:
  std::ostringstream stream_;
};

fit::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 fit::ok(zx::nsec(scalar));
  }
  if (units == "ms") {
    return fit::ok(zx::msec(scalar));
  }
  if (units == "us") {
    return fit::ok(zx::usec(scalar));
  }
  return Error() << "String duration \"" << duration << "\" has unrecognized units \"" << units
                 << "\"!";
}

fit::result<std::string, zx::duration> ParseDuration(const rapidjson::Value& object) {
  if (object.IsInt()) {
    return fit::ok(zx::nsec(object.GetInt()));
  }
  if (object.IsString()) {
    return ParseDurationString(object.GetString());
  }
  return fit::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)
    -> fit::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 fit::ok(std::cref(object[name]));
}

template <typename... Context>
fit::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 fit::ok(result->get().GetInt());
}

template <typename... Context>
fit::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 fit::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>
fit::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 fit::ok(result->get().GetUint());
}

std::optional<zx_profile_info_t> ParseThreadProfile(const std::string& filename,
                                                    const char* profile_name,
                                                    const rapidjson::Value::Member& profile) {
  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_SLOG(WARNING, result.error_value().c_str(), FX_KV("profile_name", profile_name),
              FX_KV("tag", "ProfileProvider"));
      return std::nullopt;
    }
  } else if (!has_priority && has_complete_deadline) {
    auto capacity_result = ParseDuration(profile.value["capacity"]);
    if (capacity_result.is_error()) {
      FX_SLOG(WARNING, capacity_result.error_value().c_str(), FX_KV("profile_name", profile_name),
              FX_KV("tag", "ProfileProvider"));
      return std::nullopt;
    }
    auto deadline_result = ParseDuration(profile.value["deadline"]);
    if (deadline_result.is_error()) {
      FX_SLOG(WARNING, deadline_result.error_value().c_str(), FX_KV("profile_name", profile_name),
              FX_KV("tag", "ProfileProvider"));
      return std::nullopt;
    }
    auto period_result = ParseDuration(profile.value["period"]);
    if (period_result.is_error()) {
      FX_SLOG(WARNING, period_result.error_value().c_str(), FX_KV("profile_name", profile_name),
              FX_KV("tag", "ProfileProvider"));
      return std::nullopt;
    }
    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_SLOG(WARNING, "Priority and deadline parameters are mutually exclusive!",
            FX_KV("filename", filename), FX_KV("profile_name", profile_name),
            FX_KV("tag", "ProfileProvider"));
    return std::nullopt;
  } else if (!has_priority && !has_complete_deadline && has_some_deadline) {
    FX_SLOG(WARNING, "Deadline profiles must specify \"capacity\", \"deadline\", and \"period\"!",
            FX_KV("filename", filename), FX_KV("profile_name", profile_name),
            FX_KV("tag", "ProfileProvider"));
    return std::nullopt;
  }

  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_SLOG(WARNING,
                  "Array element of profile member \"affinity\" must be an "
                  "unsigned integer!",
                  FX_KV("element_count", element_count), FX_KV("filename", filename),
                  FX_KV("profile_name", profile_name), FX_KV("tag", "ProfileProvider"));
          failed = true;
          break;
        }

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

        if (cpu_number >= ZX_CPU_SET_MAX_CPUS) {
          FX_SLOG(WARNING, "Profile member \"affinity\" must be an integer < ZX_CPU_SET_MAX_CPUS",
                  FX_KV("filename", filename), FX_KV("profile_name", profile_name),
                  FX_KV("ZX_CPU_SET_MAX_CPUS", ZX_CPU_SET_MAX_CPUS),
                  FX_KV("tag", "ProfileProvider"));
          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) {
        return std::nullopt;
      }
    } else {
      FX_SLOG(WARNING, "Profile member \"affinity\" must be a uint64 or an array of CPU indices!",
              FX_KV("filename", filename), FX_KV("profile_name", profile_name),
              FX_KV("tag", "ProfileProvider"));
      return std::nullopt;
    }
  }  // if (has_affinity)

  return info;
}

std::optional<zx_profile_info_t> ParseMemoryProfile(const std::string& filename,
                                                    const char* profile_name,
                                                    const rapidjson::Value::Member& profile) {
  const bool has_priority = profile.value.HasMember("priority");

  zx_profile_info_t info{};
  if (has_priority) {
    auto result = GetInt("priority", profile.value, "Profile ", profile_name);
    if (result.is_ok()) {
      info.flags = ZX_PROFILE_INFO_FLAG_MEMORY_PRIORITY;
      info.priority = std::clamp<int32_t>(result.value(), ZX_PRIORITY_LOWEST, ZX_PRIORITY_HIGHEST);
    } else {
      FX_SLOG(WARNING, result.error_value().c_str(), FX_KV("profile_name", profile_name),
              FX_KV("tag", "ProfileProvider"));
      return std::nullopt;
    }
  }
  return info;
}

using SingleProfileParser = std::optional<zx_profile_info_t>(
    const std::string& filename, const char* profile_name, const rapidjson::Value::Member& profile);

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

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

  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_SLOG(WARNING, "Invalid role scope, defaulting to none!", FX_KV("filename", filename),
                FX_KV("scope", *result), FX_KV("tag", "ProfileProvider"));
      }
    }
  } else {
    FX_SLOG(WARNING, "Missing role scope, defaulting to none!", FX_KV("filename", filename));
  }

  for (const auto& profile : IterateMembers(profile_member)) {
    const char* profile_name = profile.name.GetString();
    if (!profile.value.IsObject()) {
      FX_SLOG(WARNING, "Profile value must be a JSON object!", FX_KV("filename", filename),
              FX_KV("type", type_name), FX_KV("profile", profile_name),
              FX_KV("tag", "ProfileProvider"));
      continue;
    }

    fit::result role = Role::Create(profile_name);
    if (role.is_error()) {
      FX_SLOG(WARNING, "Failed to create role from JSON object!", FX_KV("filename", filename),
              FX_KV("type", type_name), FX_KV("profile", profile_name),
              FX_KV("tag", "ProfileProvider"));
      continue;
    }

    auto result = parser(filename, profile_name, profile);
    if (!result.has_value()) {
      continue;
    }

    zx_profile_info_t& info = *result;

    if (info.flags == 0) {
      FX_SLOG(WARNING, "Ignoring empty profile.", FX_KV("filename", filename),
              FX_KV("type", type_name), FX_KV("profile_name", profile_name),
              FX_KV("tag", "ProfileProvider"));
      continue;
    }

    std::vector<Parameter> output_parameters = {};
    if (profile.value.HasMember("output_parameters")) {
      const auto& output_param_member = profile.value["output_parameters"];
      if (!output_param_member.IsObject()) {
        FX_SLOG(WARNING, "Output parameters must be a JSON object!", FX_KV("filename", filename),
                FX_KV("type", type_name), FX_KV("profile", profile_name),
                FX_KV("tag", "ProfileProvider"));
        continue;
      }
      for (const auto& m : IterateMembers(output_param_member)) {
        if (m.value.IsInt()) {
          output_parameters.push_back(
              Parameter{m.name.GetString(), ParameterValue::WithIntValue(m.value.GetInt())});
        } else if (m.value.IsDouble()) {
          output_parameters.push_back(
              Parameter{m.name.GetString(), ParameterValue::WithFloatValue(m.value.GetDouble())});
        } else if (m.value.IsString()) {
          output_parameters.push_back(
              Parameter{m.name.GetString(), ParameterValue::WithStringValue(m.value.GetString())});
        } else {
          FX_SLOG(WARNING, "Output parameter value must be a float, integer, or string!",
                  FX_KV("parameter_name", m.name.GetString()), FX_KV("filename", filename),
                  FX_KV("type", type_name), FX_KV("profile", profile_name),
                  FX_KV("tag", "ProfileProvider"));
        }
      }
    }

    Profile p(scope, info, output_parameters);
    const auto [iter, added] = profiles->insert(std::pair{std::move(role.value()), std::move(p)});
    if (!added) {
      const ProfileScope existing_scope = iter->second.scope;
      if (existing_scope >= scope) {
        FX_SLOG(WARNING, "Profile already exists at scope.", FX_KV("filename", filename),
                FX_KV("profile_name", profile_name),
                FX_KV("existing_scope", ToString(existing_scope)), FX_KV("type", type_name),
                FX_KV("profile_name", profile_name), FX_KV("scope", ToString(scope)),
                FX_KV("tag", "ProfileProvider"));
        continue;
      }
      if (iter->second.scope < scope) {
        FX_SLOG(INFO, "Profile overridden at scope.", FX_KV("filename", filename),
                FX_KV("type", type_name), FX_KV("profile_name", profile_name),
                FX_KV("scope", ToString(scope)), FX_KV("profile_name", profile_name),
                FX_KV("tag", "ProfileProvider"));
        iter->second = Profile(scope, info, std::move(output_parameters));
      }
    }
  }  // for (const auto& profile : IterateMembers(document))
}

}  // anonymous namespace

namespace zircon_profile {

fit::result<std::string, ConfiguredProfiles> 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_SLOG(WARNING, "Failed to open config dir.", FX_KV("config_path", config_path),
            FX_KV("error", strerror(errno)), FX_KV("tag", "ProfileProvider"));
    return fit::ok(ConfiguredProfiles{});
  }

  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 << " 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));
  };

  ConfiguredProfiles profiles;

  // Define fuchsia.default at builtin scope to prevent overrides from config files.
  {
    zx_profile_info_t info{};
    info.flags = ZX_PROFILE_INFO_FLAG_PRIORITY;
    info.priority = ZX_PRIORITY_DEFAULT;
    fit::result default_role_result = Role::Create("fuchsia.default");
    ZX_DEBUG_ASSERT(default_role_result.is_ok());
    auto [iter, added] = profiles.thread.emplace(std::move(default_role_result.value()),
                                                 Profile{ProfileScope::Builtin, info});
    ZX_DEBUG_ASSERT(added);
  }
  {
    zx_profile_info_t info{};
    info.flags = ZX_PROFILE_INFO_FLAG_MEMORY_PRIORITY;
    info.priority = ZX_PRIORITY_DEFAULT;
    fit::result default_role_result = Role::Create("fuchsia.default");
    ZX_DEBUG_ASSERT(default_role_result.is_ok());
    auto [iter, added] = profiles.memory.emplace(std::move(default_role_result.value()),
                                                 Profile{ProfileScope::Builtin, info});
    ZX_DEBUG_ASSERT(added);
  }

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

    FX_SLOG(INFO, "Loading config.", FX_KV("config_path", entry), FX_KV("tag", "ProfileProvider"));

    std::string data;
    if (!files::ReadFileToStringAt(dir_fd.get(), entry, &data)) {
      FX_SLOG(WARNING, "Failed to read file.", FX_KV("config_path", entry),
              FX_KV("error", strerror(errno)), FX_KV("tag", "ProfileProvider"));
      continue;
    }

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

    if (document.HasParseError()) {
      FX_SLOG(WARNING, "Failed to parse config.", FX_KV("config_path", entry),
              FX_KV("error", GetErrorMessage(document, data)), FX_KV("tag", "ProfileProvider"));
      continue;
    }

    ParseProfiles(entry, document, "profiles", ParseThreadProfile, &profiles.thread);
    ParseProfiles(entry, document, "memory", ParseMemoryProfile, &profiles.memory);
  }

  auto log_profiles = [](ProfileMap& profiles) {
    for (const auto& [key, value] : profiles) {
      FX_SLOG(DEBUG, "Loaded profile.", FX_KV("key", key.name()),
              FX_KV("scope", ToString(value.scope)), FX_KV("info", ToString(value.info)),
              FX_KV("tag", "ProfileProvider"),
              FX_KV("output_parameters", ToString(value.output_parameters)));
    }
  };
  FX_SLOG(DEBUG, "Loaded thread profiles:");
  log_profiles(profiles.thread);
  FX_SLOG(DEBUG, "Defined memory profiles:");
  log_profiles(profiles.memory);

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

fit::result<zx_status_t, Role> Role::Create(std::string_view name,
                                            std::vector<Parameter> selectors) {
  // Validate the name. It should have no selectors embedded in it.
  Role role;
  if (!re2::RE2::FullMatch(name, kReRoleName, &role.name_)) {
    FX_SLOG(WARNING, "Bad role name.", FX_KV("role_name", name), FX_KV("tag", "RoleManager"));
    return fit::error(ZX_ERR_INVALID_ARGS);
  }
  for (auto selector : selectors) {
    role.selectors_.insert(std::pair{selector.key(), selector.value()});
  }
  return fit::ok(std::move(role));
}

// ToLong attempts to convert the given string into a long and populates *out with the result.
// Returns true if str is indeed a long, false otherwise.
bool ToLong(std::string str, long* out) {
  char* end = nullptr;
  long value = std::strtol(str.c_str(), &end, 10);
  if (end == str.c_str() || *end != '\0' || value == LONG_MAX || value == LONG_MIN) {
    return false;
  }
  *out = value;
  return true;
}

// ToDouble attempts to convert the given string into a long and populates *out with the result.
// Returns true if str is indeed a double, false otherwise.
// Note that this will return true for any whole number, so it's important that the caller checks
// if the number is a long using ToLong before calling this function.
bool ToDouble(std::string str, double* out) {
  char* end = nullptr;
  double value = std::strtod(str.c_str(), &end);
  if (end == str.c_str() || *end != '\0' || value == HUGE_VAL) {
    return false;
  }
  *out = value;
  return true;
}

fit::result<zx_status_t, Role> Role::Create(std::string_view name_with_selectors,
                                            bool ignore_selectors) {
  Role role;
  std::string selectors;
  if (!re2::RE2::FullMatch(name_with_selectors, kReRoleParts, &role.name_, &selectors)) {
    FX_SLOG(WARNING, "Bad selector.", FX_KV("role_selector", name_with_selectors),
            FX_KV("tag", "RoleManager"));
    return fit::error(ZX_ERR_INVALID_ARGS);
  }

  // If the caller wants to us to ignore the selectors, exit early.
  if (ignore_selectors) {
    return fit::ok(std::move(role));
  }

  // Parse the selectors.
  re2::StringPiece input{selectors};
  std::string key, raw_value;
  while (re2::RE2::Consume(&input, kReSelector, &key, &raw_value)) {
    ParameterValue value = ParameterValue::WithStringValue(raw_value);
    long l;
    double d;
    if (ToLong(raw_value, &l)) {
      value = ParameterValue::WithIntValue(l);
    } else if (ToDouble(raw_value, &d)) {
      value = ParameterValue::WithFloatValue(d);
    }
    const auto [iter, added] = role.selectors_.emplace(key, value);
    if (!added) {
      FX_SLOG(WARNING, "Duplicate key in selector.", FX_KV("key", key), FX_KV("value", raw_value),
              FX_KV("role_selector", name_with_selectors), FX_KV("tag", "RoleManager"));
    }
  }
  return fit::ok(std::move(role));
}

bool Role::HasSelector(std::string selector) const {
  auto search = selectors_.find(selector);
  return search != selectors_.end();
}

fit::result<fit::failed, MediaRole> Role::ToMediaRole() const {
  const auto realm_iter = selectors_.find("realm");
  if (realm_iter == selectors_.end() || realm_iter->second.string_value().value() != "media") {
    return fit::failed{};
  }

  const auto capacity_iter = selectors_.find("capacity");
  const auto deadline_iter = selectors_.find("deadline");
  if (capacity_iter == selectors_.end() || deadline_iter == selectors_.end()) {
    return fit::failed{};
  }

  if (capacity_iter->second.Which() != ParameterValue::Tag::kIntValue) {
    FX_SLOG(WARNING, "Media role has invalid capacity selector.", FX_KV("role_name", name_),
            FX_KV("tag", "ProfileProvider"));
    return fit::failed{};
  }
  int64_t capacity = capacity_iter->second.int_value().value();

  if (deadline_iter->second.Which() != ParameterValue::Tag::kIntValue) {
    FX_SLOG(WARNING, "Media role has invalid deadline selector.", FX_KV("role_name", name_),
            FX_KV("tag", "ProfileProvider"));
    return fit::failed{};
  }
  int64_t deadline = deadline_iter->second.int_value().value();

  return fit::ok(MediaRole{.capacity = capacity, .deadline = deadline});
}

bool Role::operator==(const Role& other) const {
  // The role names must be the same.
  if (name_ != other.name_) {
    return false;
  }
  // The other role must have the exact same selectors as this one.
  if (selectors_.size() != other.selectors_.size()) {
    return false;
  }
  for (auto selector : selectors_) {
    auto it = other.selectors_.find(selector.first);
    if (it == other.selectors_.end()) {
      return false;
    }
    if (selector.second.Which() != it->second.Which()) {
      return false;
    }
    switch (selector.second.Which()) {
      case ParameterValue::Tag::kIntValue:
        if (selector.second.int_value().value() != it->second.int_value().value()) {
          return false;
        }
        break;
      case ParameterValue::Tag::kFloatValue:
        if (selector.second.float_value().value() != it->second.float_value().value()) {
          return false;
        }
        break;
      case ParameterValue::Tag::kStringValue:
        if (selector.second.string_value().value() != it->second.string_value().value()) {
          return false;
        }
        break;
      default:
        // We should never hit this case.
        return false;
    }
  }
  return true;
}

}  // namespace zircon_profile
