#ifndef PRODUCTION_BORG_MGMT_NODE_PROXY_SAFEPOWER_SAFEPOWER_AGENT_STATE_FIELDS_H_
#define PRODUCTION_BORG_MGMT_NODE_PROXY_SAFEPOWER_SAFEPOWER_AGENT_STATE_FIELDS_H_

#include <string>
#include <tuple>

#include "safepower_agent.pb.h"
#include "absl/strings/string_view.h"

namespace safepower_agent {

template <typename Proto, typename FieldT>
class FieldDef {
 public:
  explicit constexpr FieldDef(FieldT (Proto::*get)() const,
                              bool (Proto::*has)() const,
                              void (Proto::*set)(FieldT))
      : get_(get), has_(has), set_(set) {}

  FieldT get_from(const Proto& proto) const { return (proto.*get_)(); }
  bool is_in(const Proto& proto) const { return (proto.*has_)(); }
  void set_in(Proto& proto, FieldT value) const { (proto.*set_)(value); }

 private:
  FieldT (Proto::*get_)() const;
  bool (Proto::*has_)() const;
  void (Proto::*set_)(FieldT);
};

template <typename Proto, typename FieldT>
FieldDef(FieldT (Proto::*get)() const, bool (Proto::*has)() const,
         void (Proto::*set)(FieldT)) -> FieldDef<Proto, FieldT>;

template <typename Proto>
class FieldDef<Proto, std::string> {
 public:
  explicit constexpr FieldDef(const std::string& (Proto::*get)() const,
                              bool (Proto::*has)() const,
                              void (Proto::*set)(const std::string&))
      : get_(get), has_(has), set_(set) {}

  const std::string& get_from(const Proto& proto) const {
    return (proto.*get_)();
  }
  bool is_in(const Proto& proto) const { return (proto.*has_)(); }
  void set_in(Proto& proto, absl::string_view value) const {
    (proto.*set_)(value);
  }

 private:
  const std::string& (Proto::*get_)() const;
  bool (Proto::*has_)() const;
  void (Proto::*set_)(const std::string&);
};

template <typename Proto, typename FieldT>
class MessageFieldDef {
 public:
  explicit constexpr MessageFieldDef(FieldT* (Proto::*get_mutable)(),
                                     const FieldT& (Proto::*get)() const,
                                     bool (Proto::*has)() const)
      : get_mutable_(get_mutable), get_(get), has_(has) {}

  const FieldT& get_from(const Proto& proto) const { return (proto.*get_)(); }
  FieldT* get_mutable_from(Proto& proto) const {
    return (proto.*get_mutable_)();
  }
  bool is_in(const Proto& proto) const { return (proto.*has_)(); }

 private:
  FieldT* (Proto::*get_mutable_)();
  const FieldT& (Proto::*get_)() const;
  bool (Proto::*has_)() const;
};

template <typename Proto, typename FieldT>
MessageFieldDef(FieldT* (Proto::*get_mutable)(),
                const FieldT& (Proto::*get)() const, bool (Proto::*has)() const)
    -> MessageFieldDef<Proto, FieldT>;

template <typename Proto, typename FieldT>
class MapFieldDef {
 public:
  explicit constexpr MapFieldDef(FieldT* (Proto::*get_mutable)(),
                                 const FieldT& (Proto::*get)() const)
      : get_mutable_(get_mutable), get_(get) {}

  const FieldT& get_from(const Proto& proto) const { return (proto.*get_)(); }
  FieldT* get_mutable_from(Proto& proto) const {
    return (proto.*get_mutable_)();
  }

 private:
  FieldT* (Proto::*get_mutable_)();
  const FieldT& (Proto::*get_)() const;
};

template <typename Proto, typename FieldT>
MapFieldDef(FieldT* (Proto::*get_mutable)(),
            const FieldT& (Proto::*get)() const, bool (Proto::*has)() const)
    -> MapFieldDef<Proto, FieldT>;

template <typename Proto>
struct ProtoFields {
  // static constexpr std::tuple kFields; is not defined here so we have a
  // compiler error if we forget to define it for some type.
};

#define FIELD_DEF(Proto, field_name)                     \
  FieldDef(&Proto::field_name, &Proto::has_##field_name, \
           &Proto::set_##field_name)

#define MESSAGE_FIELD_DEF(Proto, field_name)                        \
  MessageFieldDef(&Proto::mutable_##field_name, &Proto::field_name, \
                  &Proto::has_##field_name)

#define MAP_FIELD_DEF(Proto, field_name) \
  MapFieldDef(&Proto::mutable_##field_name, &Proto::field_name)

// LINT.IfChange(SystemStateFields)
template <>
struct ProtoFields<safepower_agent_proto::DaemonState> {
  static constexpr std::tuple kFields = {
      FIELD_DEF(safepower_agent_proto::DaemonState, healthy),
      FIELD_DEF(safepower_agent_proto::DaemonState, restart_counter),
  };
};

template <>
struct ProtoFields<safepower_agent_proto::BootState> {
  static constexpr std::tuple kFields = {
      FIELD_DEF(safepower_agent_proto::BootState, boot_counter),
      FIELD_DEF(safepower_agent_proto::BootState, uptime_ms),
      FIELD_DEF(safepower_agent_proto::BootState, state),
  };
};

template <>
struct ProtoFields<safepower_agent_proto::ConnectionState> {
  static constexpr std::tuple kFields = {
      FIELD_DEF(safepower_agent_proto::ConnectionState, reconnect_counter),
  };
};

template <>
struct ProtoFields<safepower_agent_proto::PowerState> {
  static constexpr std::tuple kFields = {
      FIELD_DEF(safepower_agent_proto::PowerState, state),
      FIELD_DEF(safepower_agent_proto::PowerState, power_cycle_counter),
  };
};

template <>
struct ProtoFields<safepower_agent_proto::NodeState> {
  static constexpr std::tuple kFields = {
      MESSAGE_FIELD_DEF(safepower_agent_proto::NodeState, boot_state),
      MESSAGE_FIELD_DEF(safepower_agent_proto::NodeState, power_state),
      MAP_FIELD_DEF(safepower_agent_proto::NodeState, daemon_state),
  };
};

template <>
struct ProtoFields<safepower_agent_proto::SystemState> {
  static constexpr std::tuple kFields = {
      FIELD_DEF(safepower_agent_proto::SystemState, epoch_ms),
      MAP_FIELD_DEF(safepower_agent_proto::SystemState, node_state),
  };
};

// LINT.ThenChange(//depot/proto/safepower_agent.proto:SystemState)
#undef FIELD_DEF
#undef MESSAGE_FIELD_DEF

}  // namespace safepower_agent
#endif  // PRODUCTION_BORG_MGMT_NODE_PROXY_SAFEPOWER_SAFEPOWER_AGENT_STATE_FIELDS_H_
