#ifndef THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_DETERMINISTIC_BMC_OFFLINE_CONFIG_PARSER_PROTO_READER_H_
#define THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_DETERMINISTIC_BMC_OFFLINE_CONFIG_PARSER_PROTO_READER_H_

#include <cstdint>
#include <filesystem>  // NOLINT
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <system_error>  // NOLINT

#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "google/protobuf/message.h"
#include "google/protobuf/text_format.h"

namespace deterministic_bmc {

enum ProtoFormat : uint8_t {
  kTextProto,
  kBinaryProto,
};

inline std::ostream& operator<<(std::ostream& os, ProtoFormat format) {
  switch (format) {
    case ProtoFormat::kTextProto:
      return os << "TextProto";
    case ProtoFormat::kBinaryProto:
      return os << "BinaryProto";
    default:
      return os << "Invalid ProtoFormat";
  }
}

template <typename T>
class ProtoReader {
 public:
  // Reads a proto from a file.
  //
  // path: The path to the file.
  // format: The format of the proto.
  //
  // Returns a proto if successful, or an error if unsuccessful.
  static absl::StatusOr<T> ReadProtoFromFile(absl::string_view path,
                                             ProtoFormat format);
};

template <typename T>
absl::StatusOr<T> ProtoReader<T>::ReadProtoFromFile(absl::string_view path,
                                                    ProtoFormat format) {
  std::error_code ec;
  if (!std::filesystem::exists(path, ec)) {
    LOG(WARNING)
        << "Proto file " << path
        << " does not exist or filesystem::exists() failed with error: "
        << (ec ? "N/A" : ec.message());
    return absl::NotFoundError(
        absl::StrCat("ProtoReader: File not found: ", path));
  }
  std::ifstream input(std::string(path), format == ProtoFormat::kBinaryProto
                                             ? std::ios::in | std::ios::binary
                                             : std::ios::in);
  if (!input.is_open()) {
    LOG(WARNING) << "Error opening file: " << path;
    return absl::InternalError(
        absl::StrCat("ProtoReader: Failed to open file: ", path));
  }

  // Read the entire file into a stringstream
  std::stringstream buffer;
  buffer << input.rdbuf();
  input.close();

  T config;
  // Parse the proto from the string
  const std::string format_str =
      (format == ProtoFormat::kBinaryProto) ? "binary" : "text";

  if (format == ProtoFormat::kBinaryProto
          ? !config.ParseFromString(buffer.str())
          : !::google::protobuf::TextFormat::ParseFromString(buffer.str(), &config)) {
    LOG(WARNING) << "Error parsing " << format_str
                 << " proto from file: " << path;
    return absl::InternalError(absl::StrCat("ProtoReader: Failed to parse ",
                                            format_str,
                                            " proto from file: ", path));
  }

  return config;
}

}  // namespace deterministic_bmc

#endif  // THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_DETERMINISTIC_BMC_OFFLINE_CONFIG_PARSER_PROTO_READER_H_
