#include "state_merge.h"

#include <tuple>

#include "safepower_agent.pb.h"
#include "state_fields.h"
#include "google/protobuf/map.h"

namespace safepower_agent {

using ::safepower_agent_proto::NodeState;
using ::safepower_agent_proto::SystemState;

template <typename Field>
concept IsMessage = requires { &Field::get_mutable_from; };

template <typename Proto>
static void Update(Proto& dest, const Proto& update);

template <typename Proto, typename Field>
inline void UpdateField(const Field& field, Proto& dest, const Proto& src) {
  if (!field.is_in(src)) return;
  if constexpr (IsMessage<Field>) {
    Update(*field.get_mutable_from(dest), field.get_from(src));
  } else {
    field.set_in(dest, field.get_from(src));
  }
}

template <typename Proto, typename Key, typename Value>
inline void UpdateField(const MapFieldDef<Key, Value>& field, Proto& dest,
                        const Proto& src) {
  for (const auto& [key, value] : field.get_from(src)) {
    Update((*field.get_mutable_from(dest))[key], value);
  }
}

template <typename Proto>
static void Update(Proto& dest, const Proto& update) {
  std::apply(
      [&](auto&&... fields) { (UpdateField(fields, dest, update), ...); },
      ProtoFields<Proto>::kFields);
}

// Recursively update a map field.
template <typename Key, typename Value>
static void Update(google::protobuf::Map<Key, Value>& dest,
                   const google::protobuf::Map<Key, Value>& update) {
  for (const auto& [key, value] : update) {
    auto found = dest.find(key);
    if (found == dest.end()) {
      dest.insert({key, value});
    } else {
      Update(found->second, value);
    }
  }
}

template <>
void ApplyStateUpdate(SystemState& current_state, const SystemState& update) {
  Update(current_state, update);
}

}  // namespace safepower_agent
