#ifndef PROTOBUF_BENCHMARKS_UTIL_SCHEMA_PROTO2_TO_PROTO3_UTIL_H_
#define PROTOBUF_BENCHMARKS_UTIL_SCHEMA_PROTO2_TO_PROTO3_UTIL_H_

#include "google/protobuf/message.h"
#include "google/protobuf/descriptor.h"
#include "google/protobuf/descriptor.pb.h"

#include <sstream>
#include <algorithm>

using google::protobuf::Descriptor;
using google::protobuf::DescriptorProto;
using google::protobuf::FileDescriptorProto;
using google::protobuf::FieldDescriptorProto;
using google::protobuf::Message;
using google::protobuf::EnumValueDescriptorProto;

namespace google {
namespace protobuf {
namespace util {

class SchemaGroupStripper {

 public:
  static void StripFile(const FileDescriptor* old_file,
                        FileDescriptorProto *file) {
    for (int i = file->mutable_message_type()->size() - 1; i >= 0; i--) {
      if (IsMessageSet(old_file->message_type(i))) {
        file->mutable_message_type()->DeleteSubrange(i, 1);
        continue;
      }
      StripMessage(old_file->message_type(i), file->mutable_message_type(i));
    }
    for (int i = file->mutable_extension()->size() - 1; i >= 0; i--) {
      auto field = old_file->extension(i);
      if (field->type() == FieldDescriptor::TYPE_GROUP ||
          IsMessageSet(field->message_type()) ||
          IsMessageSet(field->containing_type())) {
        file->mutable_extension()->DeleteSubrange(i, 1);
      }
    }
  }

 private:
  static bool IsMessageSet(const Descriptor *descriptor) {
    if (descriptor != nullptr
        && descriptor->options().message_set_wire_format()) {
      return true;
    }
    return false;
  }

  static void StripMessage(const Descriptor *old_message,
                           DescriptorProto *new_message) {
    for (int i = new_message->mutable_field()->size() - 1; i >= 0; i--) {
      if (old_message->field(i)->type() == FieldDescriptor::TYPE_GROUP ||
          IsMessageSet(old_message->field(i)->message_type())) {
        new_message->mutable_field()->DeleteSubrange(i, 1);
      }
    }
    for (int i = new_message->mutable_extension()->size() - 1; i >= 0; i--) {
      auto field_type_name = new_message->mutable_extension(i)->type_name();
      if (old_message->extension(i)->type() == FieldDescriptor::TYPE_GROUP ||
          IsMessageSet(old_message->extension(i)->containing_type()) ||
          IsMessageSet(old_message->extension(i)->message_type())) {
        new_message->mutable_extension()->DeleteSubrange(i, 1);
      }
    }
    for (int i = 0; i < new_message->mutable_nested_type()->size(); i++) {
      StripMessage(old_message->nested_type(i),
                   new_message->mutable_nested_type(i));
    }
  }

};

class EnumScrubber {

 public:
  EnumScrubber()
      : total_added_(0) {
  }

  void ScrubFile(FileDescriptorProto *file) {
    for (int i = 0; i < file->enum_type_size(); i++) {
      ScrubEnum(file->mutable_enum_type(i));
    }
    for (int i = 0; i < file->mutable_message_type()->size(); i++) {
      ScrubMessage(file->mutable_message_type(i));
    }
  }

 private:
  void ScrubEnum(EnumDescriptorProto *enum_type) {
    if (enum_type->value(0).number() != 0) {
      bool has_zero = false;
      for (int j = 0; j < enum_type->value().size(); j++) {
        if (enum_type->value(j).number() == 0) {
          EnumValueDescriptorProto temp_enum_value;
          temp_enum_value.CopyFrom(enum_type->value(j));
          enum_type->mutable_value(j)->CopyFrom(enum_type->value(0));
          enum_type->mutable_value(0)->CopyFrom(temp_enum_value);
          has_zero = true;
          break;
        }
      }
      if (!has_zero) {
        enum_type->mutable_value()->Add();
        for (int i = enum_type->mutable_value()->size() - 1; i > 0; i--) {
          enum_type->mutable_value(i)->CopyFrom(
              *enum_type->mutable_value(i - 1));
        }
        enum_type->mutable_value(0)->set_number(0);
        enum_type->mutable_value(0)->set_name("ADDED_ZERO_VALUE_" +
                                              std::to_string(total_added_++));
      }
    }

  }

  void ScrubMessage(DescriptorProto *message_type) {
    for (int i = 0; i < message_type->mutable_enum_type()->size(); i++) {
      ScrubEnum(message_type->mutable_enum_type(i));
    }
    for (int i = 0; i < message_type->mutable_nested_type()->size(); i++) {
      ScrubMessage(message_type->mutable_nested_type(i));
    }
  }

  int total_added_;
};

class ExtensionStripper {
 public:
  static void StripFile(FileDescriptorProto *file) {
    for (int i = 0; i < file->mutable_message_type()->size(); i++) {
      StripMessage(file->mutable_message_type(i));
    }
    file->mutable_extension()->Clear();
  }
 private:
  static void StripMessage(DescriptorProto *message_type) {
    message_type->mutable_extension()->Clear();
    message_type->clear_extension_range();
    for (int i = 0; i < message_type->mutable_nested_type()->size(); i++) {
      StripMessage(message_type->mutable_nested_type(i));
    }
  }
};


class FieldScrubber {
 public:
  static void ScrubFile(FileDescriptorProto *file) {
    for (int i = 0; i < file->mutable_message_type()->size(); i++) {
      ScrubMessage(file->mutable_message_type(i));
    }
    for (int i = 0; i < file->mutable_extension()->size(); i++) {
      file->mutable_extension(i)->clear_default_value();
      if (ShouldClearLabel(file->mutable_extension(i))) {
        file->mutable_extension(i)->clear_label();
      }
    }
  }
 private:
  static bool ShouldClearLabel(const FieldDescriptorProto *field) {
    return field->label() == FieldDescriptorProto::LABEL_REQUIRED;
  }

  static void ScrubMessage(DescriptorProto *message_type) {
    message_type->mutable_extension()->Clear();
    for (int i = 0; i < message_type->mutable_extension()->size(); i++) {
      message_type->mutable_extension(i)->clear_default_value();
      if (ShouldClearLabel(message_type->mutable_extension(i))) {
        message_type->mutable_extension(i)->clear_label();
      }
    }
    for (int i = 0; i < message_type->mutable_field()->size(); i++) {
      message_type->mutable_field(i)->clear_default_value();
      if (ShouldClearLabel(message_type->mutable_field(i))) {
        message_type->mutable_field(i)->clear_label();
      }
    }
    for (int i = 0; i < message_type->mutable_nested_type()->size(); i++) {
      ScrubMessage(message_type->mutable_nested_type(i));
    }
  }
};

}  // namespace util
}  // namespace protobuf
}  // namespace google

#endif  // PROTOBUF_BENCHMARKS_UTIL_SCHEMA_PROTO2_TO_PROTO3_UTIL_H_
