// Copyright 2019 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 "workload.h"

#include <lib/syslog/cpp/macros.h>
#include <lib/zircon-internal/ktrace.h>
#include <lib/zx/port.h>
#include <lib/zx/profile.h>
#include <lib/zx/time.h>
#include <lib/zx/timer.h>
#include <zircon/syscalls/port.h>

#include <chrono>
#include <memory>
#include <optional>
#include <sstream>
#include <utility>
#include <vector>

#include "action.h"
#include "object.h"
#include "random.h"
#include "rapidjson/document.h"
#include "rapidjson/error/en.h"
#include "src/lib/files/file.h"
#include "utility.h"
#include "worker.h"

struct SequenceAction : ActionBase<SequenceAction, ActionDefaultCopyable::False> {
  explicit SequenceAction(std::vector<std::unique_ptr<Action>> actions)
      : actions{std::move(actions)} {}

  void Perform(Worker* worker) override {
    for (auto& action : actions) {
      action->Perform(worker);
    }
  }

  std::unique_ptr<Action> Copy() const override {
    std::vector<std::unique_ptr<Action>> actions_copy;
    for (const auto& action : actions) {
      actions_copy.emplace_back(action->Copy());
    }
    return std::make_unique<SequenceAction>(std::move(actions_copy));
  }

  std::vector<std::unique_ptr<Action>> actions;
};

struct SleepDurationAction : ActionBase<SleepDurationAction> {
  explicit SleepDurationAction(std::chrono::nanoseconds duration_ns) : duration_ns{duration_ns} {}

  void Perform(Worker* worker) override { worker->Sleep(duration_ns); }

  const std::chrono::nanoseconds duration_ns;
};

struct SleepUniformAction : ActionBase<SleepUniformAction> {
  SleepUniformAction(std::chrono::nanoseconds min_ns, std::chrono::nanoseconds max_ns)
      : min_ns{min_ns}, max_ns{max_ns} {}

  void Perform(Worker* worker) override {
    const std::chrono::nanoseconds duration_ns{random.GetUniform(min_ns.count(), max_ns.count())};
    worker->Sleep(duration_ns);
  }

  const std::chrono::nanoseconds min_ns;
  const std::chrono::nanoseconds max_ns;
  Random random;
};

struct SpinDurationAction : ActionBase<SpinDurationAction> {
  explicit SpinDurationAction(std::chrono::nanoseconds duration_ns) : duration_ns{duration_ns} {}

  void Perform(Worker* worker) override { worker->Spin(duration_ns); }

  const std::chrono::nanoseconds duration_ns;
};

struct SpinUniformAction : ActionBase<SpinUniformAction> {
  SpinUniformAction(std::chrono::nanoseconds min_ns, std::chrono::nanoseconds max_ns)
      : min_ns{min_ns}, max_ns{max_ns} {}

  void Perform(Worker* worker) override {
    const std::chrono::nanoseconds duration_ns{random.GetUniform(min_ns.count(), max_ns.count())};
    worker->Spin(duration_ns);
  }

  const std::chrono::nanoseconds min_ns;
  const std::chrono::nanoseconds max_ns;
  Random random;
};

struct YieldAction : ActionBase<YieldAction> {
  void Perform(Worker* worker) override { worker->Yield(); }
};

struct ExitAction : ActionBase<ExitAction> {
  void Perform(Worker* worker) override { worker->Exit(); }
};

struct SetProfileAction : ActionBase<SetProfileAction> {
  SetProfileAction(zx::unowned_profile profile, bool once)
      : profile{std::move(profile)}, once{once} {}

  void Perform(Worker* worker) override {
    if (!once || !completed) {
      completed = true;
      worker->SetProfile(profile);
    }
  }

  zx::unowned_profile profile;
  const bool once;
  bool completed{false};
};

struct SetTimerAction : ActionBase<SetTimerAction> {
  SetTimerAction(TimerObject timer, std::chrono::nanoseconds relative_deadline_ns,
                 std::chrono::nanoseconds timer_slack_ns)
      : timer{timer}, relative_deadline_ns{relative_deadline_ns}, timer_slack_ns{timer_slack_ns} {}

  void Perform(Worker*) override {
    const zx_status_t status =
        timer->set(zx::deadline_after(zx::duration{relative_deadline_ns.count()}),
                   zx::duration{timer_slack_ns.count()});
    FX_CHECK(status == ZX_OK);
  }

  TimerObject timer;
  const std::chrono::nanoseconds relative_deadline_ns;
  const std::chrono::nanoseconds timer_slack_ns;
};

struct ChannelWriteAction : ActionBase<ChannelWriteAction> {
  ChannelWriteAction(ChannelObject channel, size_t side, size_t bytes)
      : channel{channel},
        endpoint{side == 0 ? channel->first : channel->second},
        bytes{bytes},
        buffer(bytes) {}

  void Perform(Worker*) override {
    const auto status =
        endpoint->write(0, buffer.data(), static_cast<uint32_t>(buffer.size()), nullptr, 0);
    FX_CHECK(status == ZX_OK);
  }

  ChannelObject channel;
  zx::unowned_channel endpoint;
  size_t bytes;
  std::vector<uint8_t> buffer;
};

struct ChannelReadAction : ActionBase<ChannelReadAction> {
  ChannelReadAction(ChannelObject channel, size_t side)
      : channel{channel},
        endpoint{side == 0 ? channel->first : channel->second},
        buffer(64 * 1024) {}

  void Perform(Worker*) override {
    uint32_t actual_bytes;
    uint32_t actual_handles;
    const auto status =
        endpoint->read(0, buffer.data(), nullptr, static_cast<uint32_t>(buffer.size()), 0,
                       &actual_bytes, &actual_handles);
    FX_CHECK(status == ZX_OK) << "Failed to read channel: " << status;
  }

  ChannelObject channel;
  zx::unowned_channel endpoint;
  std::vector<uint8_t> buffer;
};

struct WaitOneAction : ActionBase<WaitOneAction> {
  WaitOneAction(zx::unowned_handle handle, zx_signals_t signals,
                std::optional<std::chrono::nanoseconds> relative_deadline_ns = std::nullopt)
      : handle{handle}, signals{signals}, relative_deadline_ns{relative_deadline_ns} {}

  void Perform(Worker*) {
    const auto absolute_deadline =
        relative_deadline_ns ? zx::deadline_after(zx::duration{relative_deadline_ns->count()})
                             : zx::time::infinite();
    const auto status = handle->wait_one(signals, absolute_deadline, nullptr);
    FX_CHECK(status == ZX_OK) << "Failed to signal object: " << status;
  }

  zx::unowned_handle handle;
  zx_signals_t signals;
  std::optional<std::chrono::nanoseconds> relative_deadline_ns;
};

struct WaitAsyncAction : ActionBase<WaitAsyncAction> {
  WaitAsyncAction(zx::unowned_port port, zx::unowned_handle handle, zx_signals_t signals)
      : port{port}, handle{handle}, signals{signals} {}

  void Perform(Worker*) override {
    const auto status = handle->wait_async(*port, 0, signals, 0);
    FX_CHECK(status == ZX_OK) << "Faild to wait async: " << status;
  }

  zx::unowned_port port;
  zx::unowned_handle handle;
  zx_signals_t signals;
};

struct PortWaitAction : ActionBase<PortWaitAction, ActionDefaultCopyable::False> {
  explicit PortWaitAction(
      PortObject port, std::optional<std::chrono::nanoseconds> relative_deadline_ns = std::nullopt)
      : port{port}, relative_deadline_ns{relative_deadline_ns} {
    RegisterTerminateEvent();
  }

  void RegisterTerminateEvent() {
    const auto status = PortObject::GetTerminateEvent()->wait_async(
        *port.object(), 0, PortObject::kTerminateSignal, 0);
    FX_CHECK(status == ZX_OK) << "Failed to wait async on terminate event: " << status;
  }

  void Perform(Worker*) override {
    zx_port_packet_t packet;
    const auto absolute_deadline =
        relative_deadline_ns ? zx::deadline_after(zx::duration{relative_deadline_ns->count()})
                             : zx::time::infinite();
    const auto status = port->wait(absolute_deadline, &packet);

    // TODO(eieio): Add option to fail or not on timeout.
    FX_CHECK(status == ZX_OK || status == ZX_ERR_TIMED_OUT) << "Failed to port wait: " << status;
  }

  std::unique_ptr<Action> Copy() const override {
    auto copy = std::make_unique<PortWaitAction>(*this);
    // Register an additional packet for every copy.
    copy->RegisterTerminateEvent();
    return copy;
  }

  PortObject port;
  const std::optional<std::chrono::nanoseconds> relative_deadline_ns;
};

struct ObjectSignalAction : ActionBase<ObjectSignalAction> {
  ObjectSignalAction(zx::unowned_handle handle, zx_signals_t clear_mask, zx_signals_t set_mask)
      : handle{handle}, clear_mask{clear_mask}, set_mask{set_mask} {}

  void Perform(Worker*) {
    const auto status = handle->signal(clear_mask, set_mask);
    FX_CHECK(status == ZX_OK) << "Failed to signal object: " << status;
  }

  zx::unowned_handle handle;
  zx_signals_t clear_mask;
  zx_signals_t set_mask;
};

// 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;
};

template <typename... Context>
const auto& GetMember(const char* name, const rapidjson::Value& object, Context&&... context) {
  FX_CHECK(object.IsObject())
      << (std::ostringstream{} << ... << std::forward<Context>(context)).rdbuf()
      << " must be a JSON object!";
  FX_CHECK(object.HasMember(name))
      << (std::ostringstream{} << ... << std::forward<Context>(context)).rdbuf()
      << " must have a \"" << name << "\" member!";
  return object[name];
}

template <typename... Context>
auto GetInt(const char* name, const rapidjson::Value& object, Context&&... context) {
  const auto& member = GetMember(name, object, std::forward<Context>(context)...);
  FX_CHECK(member.IsInt())
      << (std::ostringstream{} << ... << std::forward<Context>(context)).rdbuf() << " member \""
      << name << "\" must be an integer!";
  return member.GetInt();
}

template <typename... Context>
const auto* GetString(const char* name, const rapidjson::Value& object, Context&&... context) {
  const auto& member = GetMember(name, object, std::forward<Context>(context)...);
  FX_CHECK(member.IsString())
      << (std::ostringstream{} << ... << std::forward<Context>(context)).rdbuf() << " member \""
      << name << "\" must be a string!";
  return member.GetString();
}

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

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

template <typename... Context>
auto GetUint(const char* name, const rapidjson::Value& object, Context&&... context) {
  const auto& member = GetMember(name, object, std::forward<Context>(context)...);
  FX_CHECK(member.IsUint())
      << (std::ostringstream{} << ... << std::forward<Context>(context)).rdbuf() << " member \""
      << name << "\" must be an unsigned integer!";
  return member.GetUint();
}

void Workload::ParseObject(const std::string& name, const rapidjson::Value& object) {
  const std::string type_string = GetString("type", object, "Named object \"", name, "\"");
  if (type_string == "timer") {
    Add(name, TimerObject::Create());
  } else if (type_string == "port") {
    Add(name, PortObject::Create());
  } else if (type_string == "channel") {
    Add(name, ChannelObject::Create());
  } else if (type_string == "event") {
    Add(name, EventObject::Create());
  } else {
    FX_CHECK(false) << "Object \"" << name << "\" has unknown type \"" << type_string << "\"!";
  }
}

Workload::Duration Workload::ParseDuration(const rapidjson::Value& object) {
  if (object.IsInt()) {
    return {std::chrono::nanoseconds{object.GetInt()}};
  } else if (object.IsString()) {
    return {ParseDurationString(object.GetString())};
  } else {
    FX_CHECK(false) << "Duration must be an integer or string!";
    __builtin_unreachable();
  }
}

Workload::Uniform Workload::ParseUniform(const rapidjson::Value& object) {
  auto [min_ns] = ParseDuration(GetMember("min", object, "Uniform object"));
  auto [max_ns] = ParseDuration(GetMember("max", object, "Uniform object"));

  return {min_ns, max_ns};
}

std::variant<Workload::Duration, Workload::Uniform> Workload::ParseInterval(
    const rapidjson::Value& object, AcceptNamedIntervalFlag accept_named_interval) {
  FX_CHECK(object.IsObject()) << "Interval must be a JSON object!";

  const bool has_duration = object.HasMember("duration");
  const bool has_uniform = object.HasMember("uniform");
  const bool has_interval = object.HasMember("interval");

  FX_CHECK(accept_named_interval || !has_interval)
      << "Timespec \"interval\" is not supported in this context!";

  FX_CHECK((has_duration + has_uniform + has_interval) == 1)
      << "Interval must have exactly one timespec: either \"uniform\" or "
         "\"duration\""
      << (accept_named_interval ? " or \"interval\"" : "") << "!";

  if (has_duration) {
    return {ParseDuration(object["duration"])};
  } else if (has_uniform) {
    return {ParseUniform(object["uniform"])};
  } else if (has_interval) {
    const auto* interval_name_string = GetString("interval", object, "Interval");
    auto search = intervals_.find(interval_name_string);
    FX_CHECK(search != intervals_.end())
        << "Undefined named interval \"" << interval_name_string << "\"!";
    return search->second;
  } else {
    __builtin_unreachable();
  }
}

void Workload::ParseNamedInterval(const std::string& name, const rapidjson::Value& object) {
  FX_CHECK(object.IsObject()) << "Named interval must be a JSON object!";

  const auto result = ParseInterval(object, RejectNamedInterval);
  auto [iter, okay] = intervals_.emplace(name, result);
  FX_CHECK(okay) << "Named interval \"" << name << "\" defined more than once!";
}

zx::unowned_handle Workload::ParseTargetObjectAndGetHandle(const std::string& name,
                                                           const rapidjson::Value& object,
                                                           const std::string& context) {
  Object& target = Get(name);
  switch (target.type()) {
    case TimerObject::Type:
      return zx::unowned_handle{static_cast<TimerObject&>(target)->get()};
    case ChannelObject::Type: {
      const size_t side = GetInt("side", object, context);
      FX_CHECK(side == 0 || side == 1)
          << "Wait async action member \"side\" must be an integer value 0 or 1!";
      auto [first, second] = static_cast<ChannelObject&>(target).bind();
      return zx::unowned_handle{side == 0 ? first->get() : second->get()};
    }
    case EventObject::Type:
      return zx::unowned_handle{static_cast<EventObject&>(target)->get()};
    case PortObject::Type:
      return zx::unowned_handle{static_cast<PortObject&>(target)->get()};
    default:
      FX_CHECK(false) << "Unknown object type: " << target.type();
      __builtin_unreachable();
  }
}

std::unique_ptr<Action> Workload::ParseAction(const rapidjson::Value& action) {
  const std::string action_string = GetString("action", action, "Action");
  if (action_string == "spin") {
    const auto result = ParseInterval(action, AcceptNamedInterval);
    if (std::holds_alternative<Duration>(result)) {
      const auto [duration_ns] = std::get<Duration>(result);
      return SpinDurationAction::Create(duration_ns);
    } else /*if (std::holds_alternative<Uniform>(result))*/ {
      const auto [min_ns, max_ns] = std::get<Uniform>(result);
      return SpinUniformAction::Create(min_ns, max_ns);
    }
  } else if (action_string == "sleep") {
    const auto result = ParseInterval(action, AcceptNamedInterval);
    if (std::holds_alternative<Duration>(result)) {
      const auto [duration_ns] = std::get<Duration>(result);
      return SleepDurationAction::Create(duration_ns);
    } else /*if (std::holds_alternative<Uniform>(result))*/ {
      const auto [min_ns, max_ns] = std::get<Uniform>(result);
      return SleepUniformAction::Create(min_ns, max_ns);
    }
  } else if (action_string == "yield") {
    return YieldAction::Create();
  } else if (action_string == "write") {
    const auto* channel_name = GetString("channel", action, "Write action");
    const size_t side = GetInt("side", action, "Write action");
    const size_t bytes = GetInt("bytes", action, "Write action");
    return ChannelWriteAction::Create(Get<ChannelObject>(channel_name), side, bytes);
  } else if (action_string == "read") {
    const auto* channel_name = GetString("channel", action, "Read action");
    const size_t side = GetInt("side", action, "Read action");
    return ChannelReadAction::Create(Get<ChannelObject>(channel_name), side);
  } else if (action_string == "behavior") {
    const auto* behavior_name = GetString("name", action, "Behavior action");
    auto search = behaviors_.find(behavior_name);
    FX_CHECK(search != behaviors_.end()) << "Unknown named behavior \"" << behavior_name << "\"!";
    return search->second->Copy();
  } else if (action_string == "wait_async") {
    const auto* context = "Wait async action";
    const auto* port_name = GetString("port", action, context);
    const auto* object_name = GetString("object", action, context);
    const auto signals = GetInt("signals", action, context);

    auto& port_object = Get<PortObject>(port_name);
    zx::unowned_handle handle = ParseTargetObjectAndGetHandle(object_name, action, context);

    return WaitAsyncAction::Create(zx::unowned_port{port_object->get()}, std::move(handle),
                                   signals);
  } else if (action_string == "wait_one") {
    const auto* context = "Wait one action";
    const auto* object_name = GetString("object", action, context);
    const auto signals = GetInt("signals", action, context);

    std::optional<std::chrono::nanoseconds> relative_deadline_ns;
    if (action.HasMember("deadline")) {
      relative_deadline_ns = ParseDuration(action["deadline"]).value;
    }

    zx::unowned_handle handle = ParseTargetObjectAndGetHandle(object_name, action, context);

    return WaitOneAction::Create(std::move(handle), signals, relative_deadline_ns);
  } else if (action_string == "port_wait") {
    const auto* port_name = GetString("port", action, "Port wait action");

    std::optional<std::chrono::nanoseconds> relative_deadline_ns;
    if (action.HasMember("deadline")) {
      relative_deadline_ns = ParseDuration(action["deadline"]).value;
    }

    return PortWaitAction::Create(Get<PortObject>(port_name), relative_deadline_ns);
  } else if (action_string == "signal") {
    const auto* context = "Signal action";
    const auto* object_name = GetString("object", action, context);
    const auto clear_mask = GetInt("clear", action, context);
    const auto set_mask = GetInt("set", action, context);

    zx::unowned_handle handle = ParseTargetObjectAndGetHandle(object_name, action, context);

    return ObjectSignalAction::Create(std::move(handle), clear_mask, set_mask);
  } else if (action_string == "timer_set") {
    const auto* timer_name = GetString("timer", action, "Timer set action");
    const auto relative_deadline_ns = ParseDuration(action["deadline"]).value;
    const auto timer_slack_ns = action.HasMember("slack") ? ParseDuration(action["slack"]).value
                                                          : std::chrono::nanoseconds{0};

    auto& timer_object = Get<TimerObject>(timer_name);

    return SetTimerAction::Create(timer_object, relative_deadline_ns, timer_slack_ns);
  } else if (action_string == "exit") {
    return ExitAction::Create();
  } else {
    FX_CHECK(false) << "Unknown action \"" << action_string << "\"!";
    __builtin_unreachable();
  }
}

void Workload::ParseNamedBehavior(const std::string& name, const rapidjson::Value& behavior) {
  if (behavior.IsObject()) {
    auto [iter, okay] = behaviors_.emplace(name, ParseAction(behavior));
    FX_CHECK(okay) << "Behavior \"" << name << "\" defined more than once!";
  } else if (behavior.IsArray()) {
    std::vector<std::unique_ptr<Action>> actions;
    for (const auto& action : IterateValues(behavior)) {
      actions.emplace_back(ParseAction(action));
    }

    auto [iter, okay] = behaviors_.emplace(name, SequenceAction::Create(std::move(actions)));
    FX_CHECK(okay) << "Behavior \"" << name << "\" defined more than once!";
  } else {
    FX_CHECK(false) << "Behavior \"" << name << "\" must be a JSON object or array!";
  }
}

void Workload::ParseWorker(const rapidjson::Value& worker) {
  FX_CHECK(worker.IsObject()) << "Worker must be a JSON object!";

  WorkerConfig config;

  if (worker.HasMember("name")) {
    config.name = GetString("name", worker, "Worker");
  }

  if (worker.HasMember("group")) {
    config.group = GetString("group", worker, "Worker");
  }

  if (worker.HasMember("priority")) {
    const auto& priority_member = worker["priority"];
    const bool is_int = priority_member.IsInt();
    const bool is_object = priority_member.IsObject();
    FX_CHECK(is_int || is_object)
        << "Worker member \"priority\" must either be an integer or a JSON object!";

    if (is_int) {
      config.priority = GetInt("priority", worker, "Worker");
    } else if (is_object) {
      const bool has_capacity = priority_member.HasMember("capacity");
      const bool has_deadline = priority_member.HasMember("deadline");
      const bool has_period = priority_member.HasMember("period");
      FX_CHECK(has_capacity && has_deadline && has_period)
          << "Worker member \"priority\" must have members \"capacity\", \"deadline\", and "
             "\"period\"!";

      const zx::duration capacity{ParseDuration(priority_member["capacity"]).value.count()};
      const zx::duration deadline{ParseDuration(priority_member["deadline"]).value.count()};
      const zx::duration period{ParseDuration(priority_member["period"]).value.count()};

      config.priority = WorkerConfig::DeadlineParams{capacity, deadline, period};
    }
  }

  if (worker.HasMember("actions")) {
    const auto& actions_member = worker["actions"];
    const bool is_array = actions_member.IsArray();
    const bool is_string = actions_member.IsString();
    FX_CHECK(is_array || is_string)
        << "Worker member \"actions\" must either be a string or a JSON object!";

    if (is_array) {
      const auto& actions = GetArray("actions", worker, "Worker");
      for (const auto& action : IterateValues(actions)) {
        config.actions.emplace_back(ParseAction(action));
      }
    } else if (is_string) {
      const auto* behavior_name = GetString("actions", worker, "Worker");
      auto search = behaviors_.find(behavior_name);
      FX_CHECK(search != behaviors_.end()) << "Unknown named behavior \"" << behavior_name << "\"!";
      config.actions.emplace_back(search->second->Copy());
    }
  }

  int64_t instances = 1;
  if (worker.HasMember("instances")) {
    const auto& instances_member = worker["instances"];
    const bool is_integer = instances_member.IsInt();
    const bool is_string = instances_member.IsString();
    const bool is_object = instances_member.IsObject();
    FX_CHECK(is_integer || is_string || is_object)
        << "Worker member \"instances\" must either be an integer, string or a JSON object!";

    if (is_integer) {
      instances = GetInt("instances", worker, "Worker");
    } else if (is_string) {
      instances = ParseInstancesString(GetString("instances", worker, "Worker"));
    } else if (is_object) {
      FX_CHECK(false) << "Worker member \"instances\" expressions are not yet implemented!";
    }
  }

  if (instances <= 0) {
    FX_LOGS(WARNING) << "Worker configured with instances=" << instances << "!";
  }

  for (int i = 0; i < instances; i++) {
    workers_.emplace_back(config);
  }
}

void Workload::ParseTracing(const rapidjson::Value& tracing) {
  FX_CHECK(tracing.IsObject()) << "Tracing configuration must be a JSON object!";

  TracingConfig config;

  if (tracing.HasMember("group mask")) {
    const auto& group_mask = GetMember("group mask", tracing, "Tracing");

    if (group_mask.IsUint()) {
      config.group_mask = GetUint("group mask", tracing, "Tracing");
    } else if (group_mask.IsString()) {
      const std::string group_mask_str = GetString("group mask", tracing, "Tracing");

      if (group_mask_str == "KTRACE_GRP_ALL") {
        config.group_mask = KTRACE_GRP_ALL;
      } else if (group_mask_str == "KTRACE_GRP_META") {
        config.group_mask = KTRACE_GRP_META;
      } else if (group_mask_str == "KTRACE_GRP_LIFECYCLE") {
        config.group_mask = KTRACE_GRP_LIFECYCLE;
      } else if (group_mask_str == "KTRACE_GRP_SCHEDULER") {
        config.group_mask = KTRACE_GRP_SCHEDULER;
      } else if (group_mask_str == "KTRACE_GRP_TASKS") {
        config.group_mask = KTRACE_GRP_TASKS;
      } else if (group_mask_str == "KTRACE_GRP_IPC") {
        config.group_mask = KTRACE_GRP_IPC;
      } else if (group_mask_str == "KTRACE_GRP_IRQ") {
        config.group_mask = KTRACE_GRP_IRQ;
      } else if (group_mask_str == "KTRACE_GRP_PROBE") {
        config.group_mask = KTRACE_GRP_PROBE;
      } else if (group_mask_str == "KTRACE_GRP_ARCH") {
        config.group_mask = KTRACE_GRP_ARCH;
      } else if (group_mask_str == "KTRACE_GRP_SYSCALL") {
        config.group_mask = KTRACE_GRP_SYSCALL;
      } else if (group_mask_str == "KTRACE_GRP_VM") {
        config.group_mask = KTRACE_GRP_VM;
      } else {
        FX_LOGS(WARNING) << "Tracing enabled with unknown group mask, mask set to all groups.";
        config.group_mask = KTRACE_GRP_ALL;
      }
    } else {
      FX_CHECK(false) << "Tracing group mask must be an unsigned integer or string!";
      __builtin_unreachable();
    }
  } else /*Set default tracing group mask*/ {
    FX_LOGS(WARNING) << "Tracing enabled with no group mask specified, mask set to all groups.";
    config.group_mask = KTRACE_GRP_ALL;
  }

  if (tracing.HasMember("filepath")) {
    config.filepath = GetString("filepath", tracing, "Tracing");
  }

  if (tracing.HasMember("string ref")) {
    config.trace_string_ref = GetString("string ref", tracing, "Tracing");
  }

  tracing_ = config;
}

void GetLineAndColumnForOffset(const std::string& input, size_t offset, int32_t* output_line,
                               int32_t* output_column) {
  if (offset == 0) {
    // Errors at position 0 are assumed to be related to the whole file.
    *output_line = 0;
    *output_column = 0;
    return;
  }
  *output_line = 1;
  *output_column = 1;
  for (size_t i = 0; i < input.size() && i < offset; i++) {
    if (input[i] == '\n') {
      *output_line += 1;
      *output_column = 1;
    } else {
      *output_column += 1;
    }
  }
}

std::string GetErrorMessage(const rapidjson::Document& document, const std::string& file_data) {
  int32_t line;
  int32_t column;
  GetLineAndColumnForOffset(file_data, document.GetErrorOffset(), &line, &column);

  std::ostringstream stream;
  stream << "at " << line << ":" << column << ": " << GetParseError_En(document.GetParseError());
  return stream.str();
}

Workload Workload::Load(const std::string& path) {
  std::string file_data;
  FX_CHECK(files::ReadFileToString(path, &file_data))
      << "Failed to read workload config file \"" << path << "\"!";

  rapidjson::Document document;

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

  FX_CHECK(!document.HasParseError()) << "Error parsing workload config file \"" << path << "\" "
                                      << GetErrorMessage(document, file_data) << "!";
  FX_CHECK(document.IsObject()) << "Document must be a JSON object!";

  Workload workload;

  // Handle workload name.
  if (document.HasMember("name")) {
    workload.name_ = GetString("name", document, "Workload");
  }

  // Handle global config.
  if (document.HasMember("config")) {
    const auto& config = GetObject("config", document, "Workload");
    if (config.HasMember("priority")) {
      workload.priority_ = GetInt("priority", config, "Workload config");
    }

    if (config.HasMember("interval")) {
      const auto& interval = config["interval"];
      auto [duration_ns] = workload.ParseDuration(interval);
      workload.interval_ = duration_ns;
    }
  }

  // Handle named intervals.
  if (document.HasMember("intervals")) {
    const auto& intervals = GetObject("intervals", document, "Workload");
    for (const auto& interval : IterateMembers(intervals)) {
      workload.ParseNamedInterval(interval.name.GetString(), interval.value);
    }
  }

  // Handle global objects.
  if (document.HasMember("objects")) {
    const auto& objects = GetObject("objects", document, "Workload");
    for (const auto& object : IterateMembers(objects)) {
      workload.ParseObject(object.name.GetString(), object.value);
    }
  }

  // Handle named actions.
  if (document.HasMember("behaviors")) {
    const auto& behaviors = GetObject("behaviors", document, "Workload");
    for (const auto& behavior : IterateMembers(behaviors)) {
      workload.ParseNamedBehavior(behavior.name.GetString(), behavior.value);
    }
  }

  // Handle workers.
  if (document.HasMember("workers")) {
    const auto& workers = GetArray("workers", document, "Workload");
    for (const auto& worker : IterateValues(workers)) {
      workload.ParseWorker(worker);
    }
  }

  // Handle tracing.
  if (document.HasMember("tracing")) {
    const auto& tracing = GetObject("tracing", document, "Workload");
    workload.ParseTracing(tracing);
  }

  return workload;
}
