#ifndef THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_CONFIG_ENTITY_CONFIG_JSON_IMPL_H_
#define THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_CONFIG_ENTITY_CONFIG_JSON_IMPL_H_

#include <stdbool.h>

#include <cstddef>
#include <cstdint>
#include <optional>
#include <tuple>
#include <utility>

#pragma GCC diagnostic push
#pragma GCC diagnostic warning "-Wconversion"

#include <memory>
#include <string>
#include <string_view>
#include <vector>

#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/numbers.h"
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "g3/macros.h"
#include "nlohmann/json.hpp"
#include "tlbmc/collector/sensor_collector.h"
#include "tlbmc/configs/entity_config.h"
#include "fan_controller_config.pb.h"
#include "fan_pwm_config.pb.h"
#include "fan_tach_config.pb.h"
#include "hwmon_temp_sensor_config.pb.h"
#include "intel_cpu_sensor_config.pb.h"
#include "nic_telemetry_config.pb.h"
#include "psu_sensor_config.pb.h"
#include "reading_range_config.pb.h"
#include "reading_transform_config.pb.h"
#include "shared_mem_sensor_config.pb.h"
#include "threshold_config.pb.h"
#include "topology_config.pb.h"
#include "virtual_sensor_config.pb.h"
#include "tlbmc/rcu/simple_rcu.h"
#include "fru.pb.h"
#include "router_interface.h"
#include "google/protobuf/json/json.h"
#include "google/protobuf/util/json_util.h"

namespace milotic_tlbmc {

struct FruKey {
  size_t bus;
  size_t address;
  // key_str is the string representation of the unique identifier of the FRU.
  // This is used to sort the FRU when bus and address are defined.
  // key_str may be one of:
  //    1. the name of the FRU if the ProbeV2 is TRUE, meaning that there is no
  //    bus or address associated with the FRU
  //    2. the bus:address of the FRU, a scanned FRU matches and valid
  //    bus/address are assigned to this FRU
  std::string key_str;

  explicit FruKey(const std::string& key) : bus(0), address(0), key_str(key) {
    std::pair<absl::string_view, absl::string_view> key_split =
        absl::StrSplit(key, ':');
    if (!absl::SimpleAtoi(key_split.first, &bus) ||
        (!absl::SimpleAtoi(key_split.second, &address) &&
         !absl::SimpleHexAtoi(key_split.second, &address))) {
      LOG(INFO) << "Failed to parse bus and address from: " << key;
      bus = 0;
      address = 0;
    }
  }

  // In the case bus and address are undefined, order does not matter as this is
  // a TRUE probe
  bool operator<(const FruKey& other) const {
    return std::tie(bus, address) < std::tie(other.bus, other.address);
  }

  std::string ToString() const { return key_str; }
};

struct ProbedConfigData {
  nlohmann::json config;
  std::vector<FruKey> fru_keys;
};

struct EntityConfigJsonImplImmutableData {
  std::vector<HwmonTempSensorConfig> hwmon_temp_sensor_configs;
  std::vector<PsuSensorConfig> psu_sensor_configs;
  std::vector<FanControllerConfig> fan_controller_configs;
  std::vector<FanPwmConfig> fan_pwm_configs;
  std::vector<FanTachConfig> fan_tach_configs;
  std::vector<SharedMemSensorConfig> shared_mem_sensor_configs;
  std::vector<IntelCpuSensorConfig> intel_cpu_sensor_configs;
  std::vector<VirtualSensorConfig> virtual_sensor_configs;
  std::vector<NicTelemetryConfig> nic_telemetry_configs;
};

struct EntityConfigJsonImplMutableData {
  absl::Status parsed_status;
  TopologyConfig topology_config;
  FruTable fru_table;
};

// This is just an aggregation of the immutable and mutable data.
// This is how the data will actually be stored within the EntityConfigJsonImpl
// class.
struct EntityConfigJsonImplData {
  EntityConfigJsonImplImmutableData immutable_data;
  EntityConfigJsonImplMutableData mutable_data;
  size_t max_updates_to_mutable_data;
};

// This is how the data will actually be stored within the EntityConfigJsonImpl
// class.
struct EntityConfigJsonImplDataStore {
  const EntityConfigJsonImplImmutableData immutable_data = {};
  SimpleRcu<EntityConfigJsonImplMutableData> mutable_data;
};
class EntityConfigJsonImpl : public EntityConfig {
 public:
  enum class ReloadType : std::uint8_t {
    kReloadAll = 0,
    kReloadFruAndTopologyOnly,
  };

  // Creates an entity config from a directory of JSON files and a FRU table.
  static absl::StatusOr<std::unique_ptr<EntityConfig>> Create(
      std::vector<nlohmann::json>&& config_list, const RawFruTable& fru_table,
      size_t ad_hoc_fru_count);

  static absl::StatusOr<std::vector<nlohmann::json>>
  ParseJsonFilesIntoConfigList(absl::string_view config_location);

  absl::StatusOr<absl::Span<const HwmonTempSensorConfig>>
  GetAllHwmonTempSensorConfigs() const override {
    ECCLESIA_RETURN_IF_ERROR(GetParsedStatus());
    return data_store_.immutable_data.hwmon_temp_sensor_configs;
  }

  absl::StatusOr<absl::Span<const PsuSensorConfig>> GetAllPsuSensorConfigs()
      const override {
    ECCLESIA_RETURN_IF_ERROR(GetParsedStatus());

    return data_store_.immutable_data.psu_sensor_configs;
  }

  absl::StatusOr<absl::Span<const FanControllerConfig>>
  GetAllFanControllerConfigs() const override {
    ECCLESIA_RETURN_IF_ERROR(GetParsedStatus());

    return data_store_.immutable_data.fan_controller_configs;
  }

  absl::StatusOr<absl::Span<const FanPwmConfig>> GetAllFanPwmConfigs()
      const override {
    ECCLESIA_RETURN_IF_ERROR(GetParsedStatus());

    return data_store_.immutable_data.fan_pwm_configs;
  }

  absl::StatusOr<absl::Span<const FanTachConfig>> GetAllFanTachConfigs()
      const override {
    ECCLESIA_RETURN_IF_ERROR(GetParsedStatus());

    return data_store_.immutable_data.fan_tach_configs;
  }

  absl::StatusOr<absl::Span<const SharedMemSensorConfig>>
  GetAllSharedMemSensorConfigs() const override {
    ECCLESIA_RETURN_IF_ERROR(GetParsedStatus());
    return data_store_.immutable_data.shared_mem_sensor_configs;
  }

  absl::StatusOr<absl::Span<const IntelCpuSensorConfig>>
  GetAllIntelCpuSensorConfigs() const override {
    ECCLESIA_RETURN_IF_ERROR(GetParsedStatus());
    return data_store_.immutable_data.intel_cpu_sensor_configs;
  }

  absl::StatusOr<absl::Span<const VirtualSensorConfig>>
  GetAllVirtualSensorConfigs() const override {
    ECCLESIA_RETURN_IF_ERROR(GetParsedStatus());
    return data_store_.immutable_data.virtual_sensor_configs;
  }

  absl::StatusOr<absl::Span<const NicTelemetryConfig>>
  GetAllNicTelemetryConfigs() const override {
    ECCLESIA_RETURN_IF_ERROR(GetParsedStatus());
    return data_store_.immutable_data.nic_telemetry_configs;
  }

  absl::StatusOr<const TopologyConfigNode*> GetFruTopology(
      absl::string_view fru_key) const override;

  absl::StatusOr<std::string> GetFruDevpath(
      absl::string_view fru_key) const override;

  absl::StatusOr<const TopologyConfigNode*> GetFruTopologyByConfig(
      absl::string_view config_key) const override;

  absl::StatusOr<const TopologyConfig*> GetTopologyConfig() const override;

  absl::StatusOr<std::vector<std::string>> GetAllConfigKeys() const override;

  absl::StatusOr<std::string> GetConfigKeyByFruKey(
      absl::string_view fru_key) const override;

  absl::StatusOr<std::string> GetFruKeyByConfigKey(
      absl::string_view config_key) const override;

  absl::StatusOr<const Fru*> GetFru(absl::string_view key) const override;

  absl::StatusOr<const FruTable*> GetAllFrus() const override;

  void UpdateFruAndTopology(const RawFruTable& fru_table,
                            const RawFru& raw_fru) override;

  nlohmann::json ToJson() const override;

  void SetSmartRouter(::crow::RouterInterface* smart_router) override;

  void SetSensorCollector(SensorCollector* sensor_collector) override;

 protected:
  explicit EntityConfigJsonImpl(std::vector<nlohmann::json>&& config_list,
                                const RawFruTable& fru_table,
                                size_t ad_hoc_fru_count);
  EntityConfigJsonImpl() = default;

  EntityConfigJsonImplData ReloadConfig(const RawFruTable& fru_table,
                                        size_t ad_hoc_fru_count,
                                        ReloadType reload_type);

  EntityConfigJsonImplImmutableData LoadMutableDataAndReturnImmutableData(
      const RawFruTable& fru_table);

  static absl::Status ParseAndPopulateConfig(
      EntityConfigJsonImplImmutableData& data, const nlohmann::json& element,
      absl::string_view config_name_with_index, bool is_subfru,
      bool is_detected);

  // Returns the type of the hardware monitor temperature sensor. If the type is
  // not supported, returns HwmonTempSensorType::kUnknown.
  static HwmonTempSensorType IsHwmonTempSensor(std::string_view type);

  // Returns the type of the PSU sensor. If the type is not supported, returns
  // PsuSensorType::kUnknown.
  static PsuSensorType IsPsuSensor(std::string_view type);

  static FanControllerType IsFanController(std::string_view type);

  static FanPwmType IsFanPwm(std::string_view type);

  static FanTachType IsFanTach(std::string_view type);

  static SharedMemSensorType IsSharedMemSensor(std::string_view type);

  static IntelCpuSensorType IsIntelCpuSensor(std::string_view type);

  static bool IsVirtualSensor(std::string_view type);

  static bool IsFan(std::string_view type);

  static bool IsNicTelemetry(std::string_view type);

  // Parses the Hwmon common config from the JSON config.
  static absl::StatusOr<HalCommonConfig> ParseHalCommonConfig(
      const nlohmann::json& config);

  static absl::StatusOr<ThresholdType> ParseThresholdType(
      std::string_view name);

  // Parses the threshold configs from the JSON config.
  // If no label is specified, the empty string is used as the label.
  static absl::StatusOr<absl::flat_hash_map<std::string, ThresholdConfigs>>
  ParseThresholdConfigs(const nlohmann::json& config);

  static absl::StatusOr<absl::flat_hash_map<std::string, ThresholdConfigs>>
  ParseThresholdConfigsForHwmonTemp(const nlohmann::json& config,
                                    const std::vector<std::string>& labels);

  // Parses the labels from the JSON config.
  static absl::StatusOr<std::vector<std::string>> ParseLabels(
      const nlohmann::json& config);

  // Parses the NIC telemetry names from the JSON config.
  static absl::StatusOr<std::vector<nic_veeprom::NicTelemetryName>>
  ParseNicTelemetryNames(const nlohmann::json& config);

  // Parses the sensor unit from the JSON config.
  static SensorUnit ParseSensorUnit(const nlohmann::json& config);

  // Parses the reading range configs from the JSON config given labels.
  static absl::flat_hash_map<std::string, ReadingRangeConfigs>
  ParseReadingRangeConfigs(const nlohmann::json& config,
                           absl::Span<const std::string> labels);

  // Parses the reading range configs.
  static ReadingRangeConfigs ParseReadingRangeConfigs(
      const nlohmann::json& config, std::optional<double> default_min,
      std::optional<double> default_max);

  // Parses the offset and scale from the JSON config given labels.
  static absl::flat_hash_map<std::string, ReadingTransformConfig>
  ParseReadingTransformConfigs(const nlohmann::json& config,
                               absl::Span<const std::string> labels);

  // Parses the label to name map from the JSON config given labels.
  // ignore_zero_index_name is used to indicate that "Name" should not be
  // considered a zero indexed name for a label.
  // If true, ParseLabelToName will not attempt to find names with the
  // Name$index schema and set name to empty string if not found.
  static absl::StatusOr<absl::flat_hash_map<std::string, std::string>>
  ParseLabelToName(const nlohmann::json& config,
                   absl::Span<const std::string> labels,
                   bool ignore_zero_index_name = false);

  static absl::StatusOr<HwmonTempSensorConfig> ParseHwmonTempSensorConfig(
      HwmonTempSensorType type, const nlohmann::json& config, bool is_detected);

  static absl::StatusOr<PsuSensorConfig> ParsePsuSensorConfig(
      PsuSensorType type, const nlohmann::json& config, bool is_detected);

  static absl::StatusOr<FanControllerConfig> ParseFanControllerConfig(
      FanControllerType type, const nlohmann::json& config, bool is_detected);

  static absl::StatusOr<FanPwmConfig> ParseFanPwmConfig(
      FanPwmType type, const nlohmann::json& config, bool is_detected);

  static absl::StatusOr<FanTachConfig> ParseFanTachConfig(
      FanTachType type, const nlohmann::json& config, bool is_detected);

  static absl::StatusOr<SharedMemSensorConfig> ParseSharedMemSensorConfig(
      SharedMemSensorType type, const nlohmann::json& config, bool is_detected);

  static absl::StatusOr<IntelCpuSensorConfig> ParseIntelCpuSensorConfig(
      IntelCpuSensorType type, const nlohmann::json& config, bool is_detected);

  static absl::StatusOr<VirtualSensorConfig> ParseVirtualSensorConfig(
      const nlohmann::json& config, bool is_detected);

  static absl::StatusOr<NicTelemetryConfig> ParseNicTelemetryConfig(
      const nlohmann::json& config, bool is_detected);

  static absl::Status ParseProcessorConfig(
      EntityConfigJsonImplMutableData& mutable_data,
      const nlohmann::json& config, TopologyConfigNode& topology_config_node,
      std::string_view top_level_config_name);

  static absl::Status ParseFanConfig(
      EntityConfigJsonImplMutableData& mutable_data,
      const nlohmann::json& config, TopologyConfigNode& topology_config_node,
      std::string_view top_level_config_name);

  // Fill parent and child node associations in the topology config.
  static absl::Status LinkParentChildNodes(Fru& current_fru,
                                           TopologyConfigNode& current_node,
                                           Fru& downstream_fru,
                                           TopologyConfigNode& downstream_node);

  static absl::Status CreateAssociationsBetweenTopologyConfigNodes(
      TopologyConfig& topology_config, FruTable& fru_table,
      absl::flat_hash_set<absl::string_view>& expected_nodes_traversed);

  absl::Status GetParsedStatus() const;

  static void PropagateSensorsFromAssemblyToBoard(
      EntityConfigJsonImplImmutableData& data,
      const TopologyConfig& topology_config, const FruTable& fru_table);

 private:
  static EntityConfigJsonImplDataStore PackDataIntoStore(
      EntityConfigJsonImplData&& data);

  template <typename ProtoT>
  nlohmann::json ProtoToJson(const ProtoT& proto) const {
    nlohmann::json response;
    std::string json_string;
    ::google::protobuf::util::JsonPrintOptions opts;
    opts.preserve_proto_field_names = true;
    if (!::google::protobuf::json::MessageToJsonString(proto, &json_string, opts).ok()) {
      LOG(ERROR) << "Failed to convert FRU table to JSON";
      return response;
    }
    LOG(INFO) << "json_string: " << json_string;
    return nlohmann::json::parse(json_string, nullptr, false);
  }

  // These data members will only be changed by a single thread in a blocking
  // manner, and will never change afterwards.
  const std::vector<nlohmann::json> immutable_config_list_;
  EntityConfigJsonImplDataStore data_store_;

  ::crow::RouterInterface* smart_router_ = nullptr;
  SensorCollector* sensor_collector_ = nullptr;
};

}  // namespace milotic_tlbmc

#pragma GCC diagnostic pop

#endif  // THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_CONFIG_ENTITY_CONFIG_JSON_IMPL_H_
