// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google LLC.  All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd

#include "hpb_generator/gen_utils.h"

#include <algorithm>
#include <string>
#include <vector>

#include "absl/log/absl_log.h"
#include "absl/strings/ascii.h"
#include "absl/strings/escaping.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_replace.h"
#include "absl/strings/string_view.h"
#include "google/protobuf/descriptor.h"

namespace {
std::string EscapeTrigraphs(absl::string_view to_escape) {
  return absl::StrReplaceAll(to_escape, {{"?", "\\?"}});
}
}  // namespace

namespace google {
namespace protobuf {
namespace hpb_generator {

void AddEnums(const google::protobuf::Descriptor* message,
              std::vector<const google::protobuf::EnumDescriptor*>* enums) {
  enums->reserve(enums->size() + message->enum_type_count());
  for (int i = 0; i < message->enum_type_count(); i++) {
    enums->push_back(message->enum_type(i));
  }
  for (int i = 0; i < message->nested_type_count(); i++) {
    AddEnums(message->nested_type(i), enums);
  }
}

std::vector<const google::protobuf::EnumDescriptor*> SortedEnums(
    const google::protobuf::FileDescriptor* file) {
  std::vector<const google::protobuf::EnumDescriptor*> enums;
  enums.reserve(file->enum_type_count());
  for (int i = 0; i < file->enum_type_count(); i++) {
    enums.push_back(file->enum_type(i));
  }
  for (int i = 0; i < file->message_type_count(); i++) {
    AddEnums(file->message_type(i), &enums);
  }
  return enums;
}

void AddMessages(const google::protobuf::Descriptor* message,
                 std::vector<const google::protobuf::Descriptor*>* messages) {
  messages->push_back(message);
  for (int i = 0; i < message->nested_type_count(); i++) {
    AddMessages(message->nested_type(i), messages);
  }
}

std::vector<const google::protobuf::Descriptor*> SortedMessages(
    const google::protobuf::FileDescriptor* file) {
  std::vector<const google::protobuf::Descriptor*> messages;
  for (int i = 0; i < file->message_type_count(); i++) {
    AddMessages(file->message_type(i), &messages);
  }
  return messages;
}

void AddExtensionsFromMessage(
    const google::protobuf::Descriptor* message,
    std::vector<const google::protobuf::FieldDescriptor*>* exts) {
  for (int i = 0; i < message->extension_count(); i++) {
    exts->push_back(message->extension(i));
  }
  for (int i = 0; i < message->nested_type_count(); i++) {
    AddExtensionsFromMessage(message->nested_type(i), exts);
  }
}

std::vector<const google::protobuf::FieldDescriptor*> SortedExtensions(
    const google::protobuf::FileDescriptor* file) {
  const int extension_count = file->extension_count();
  const int message_type_count = file->message_type_count();

  std::vector<const google::protobuf::FieldDescriptor*> ret;
  ret.reserve(extension_count + message_type_count);

  for (int i = 0; i < extension_count; i++) {
    ret.push_back(file->extension(i));
  }
  for (int i = 0; i < message_type_count; i++) {
    AddExtensionsFromMessage(file->message_type(i), &ret);
  }

  return ret;
}

std::vector<const google::protobuf::FieldDescriptor*> FieldNumberOrder(
    const google::protobuf::Descriptor* message) {
  std::vector<const google::protobuf::FieldDescriptor*> fields;
  fields.reserve(message->field_count());
  for (int i = 0; i < message->field_count(); i++) {
    fields.push_back(message->field(i));
  }
  std::sort(
      fields.begin(), fields.end(),
      [](const google::protobuf::FieldDescriptor* a, const google::protobuf::FieldDescriptor* b) {
        return a->number() < b->number();
      });
  return fields;
}

std::string ToCamelCase(const absl::string_view input, bool lower_first) {
  bool capitalize_next = !lower_first;
  std::string result;
  result.reserve(input.size());

  for (char character : input) {
    if (character == '_') {
      capitalize_next = true;
    } else if (capitalize_next) {
      result.push_back(absl::ascii_toupper(character));
      capitalize_next = false;
    } else {
      result.push_back(character);
    }
  }

  // Lower-case the first letter.
  if (lower_first && !result.empty()) {
    result[0] = absl::ascii_tolower(result[0]);
  }

  return result;
}

std::string DefaultValue(const FieldDescriptor* field) {
  if (field->is_repeated()) {
    return "::std::false_type()";
  }
  switch (field->cpp_type()) {
    case FieldDescriptor::CPPTYPE_INT32:
      return absl::StrCat(field->default_value_int32());
    case FieldDescriptor::CPPTYPE_INT64:
      return absl::StrCat(field->default_value_int64());
    case FieldDescriptor::CPPTYPE_UINT32:
      return absl::StrCat(field->default_value_uint32());
    case FieldDescriptor::CPPTYPE_UINT64:
      return absl::StrCat(field->default_value_uint64());
    case FieldDescriptor::CPPTYPE_FLOAT:
      return absl::StrCat(field->default_value_float());
    case FieldDescriptor::CPPTYPE_DOUBLE:
      return absl::StrCat(field->default_value_double());
    case FieldDescriptor::CPPTYPE_BOOL:
      return field->default_value_bool() ? "true" : "false";
    case FieldDescriptor::CPPTYPE_MESSAGE:
      return "::std::false_type()";
    case FieldDescriptor::CPPTYPE_STRING:
      return absl::StrCat(
          "\"", EscapeTrigraphs(absl::CEscape(field->default_value_string())),
          "\"");
    default:
      // TODO: b/375460289 - implement rest of scalars
      ABSL_LOG(WARNING) << "Unsupported default value type (in-progress): <"
                        << field->cpp_type_name()
                        << "> For field: " << field->full_name();
      return "::std::false_type()";
  }
}
}  // namespace hpb_generator
}  // namespace protobuf
}  // namespace google
