/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "tools/proto_merger/proto_file.h"

#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/text_format.h>

#include "perfetto/ext/base/string_utils.h"

namespace perfetto {
namespace proto_merger {
namespace {

const char* const
    kTypeToName[google::protobuf::FieldDescriptor::Type::MAX_TYPE + 1] = {
        "ERROR",  // 0 is reserved for errors

        "double",    // TYPE_DOUBLE
        "float",     // TYPE_FLOAT
        "int64",     // TYPE_INT64
        "uint64",    // TYPE_UINT64
        "int32",     // TYPE_INT32
        "fixed64",   // TYPE_FIXED64
        "fixed32",   // TYPE_FIXED32
        "bool",      // TYPE_BOOL
        "string",    // TYPE_STRING
        "group",     // TYPE_GROUP
        "message",   // TYPE_MESSAGE
        "bytes",     // TYPE_BYTES
        "uint32",    // TYPE_UINT32
        "enum",      // TYPE_ENUM
        "sfixed32",  // TYPE_SFIXED32
        "sfixed64",  // TYPE_SFIXED64
        "sint32",    // TYPE_SINT32
        "sint64",    // TYPE_SINT64
};

const char* const
    kLabelToName[google::protobuf::FieldDescriptor::MAX_LABEL + 1] = {
        "ERROR",  // 0 is reserved for errors

        "optional",  // LABEL_OPTIONAL
        "required",  // LABEL_REQUIRED
        "repeated",  // LABEL_REPEATED
};

base::Optional<std::string> MinimizeType(const std::string& a,
                                         const std::string& b) {
  auto a_pieces = base::SplitString(a, ".");
  auto b_pieces = base::SplitString(b, ".");

  size_t skip = 0;
  for (size_t i = 0; i < std::min(a_pieces.size(), b_pieces.size()); ++i) {
    if (a_pieces[i] != b_pieces[i])
      return a.substr(skip);
    skip += a_pieces[i].size() + 1;
  }
  return base::nullopt;
}

std::string SimpleFieldTypeFromDescriptor(
    const google::protobuf::Descriptor& parent,
    const google::protobuf::FieldDescriptor& desc,
    bool packageless_type) {
  switch (desc.type()) {
    case google::protobuf::FieldDescriptor::TYPE_MESSAGE:
      if (packageless_type) {
        return base::StripPrefix(desc.message_type()->full_name(),
                                 desc.message_type()->file()->package() + ".");
      } else {
        return MinimizeType(desc.message_type()->full_name(),
                            parent.full_name())
            .value_or(desc.message_type()->name());
      }
    case google::protobuf::FieldDescriptor::TYPE_ENUM:
      if (packageless_type) {
        return base::StripPrefix(desc.enum_type()->full_name(),
                                 desc.enum_type()->file()->package() + ".");
      } else {
        return MinimizeType(desc.enum_type()->full_name(), parent.full_name())
            .value_or(desc.enum_type()->name());
      }
    default:
      return kTypeToName[desc.type()];
  }
}

std::string FieldTypeFromDescriptor(
    const google::protobuf::Descriptor& parent,
    const google::protobuf::FieldDescriptor& desc,
    bool packageless_type) {
  if (!desc.is_map())
    return SimpleFieldTypeFromDescriptor(parent, desc, packageless_type);

  std::string field_type;
  field_type += "map<";
  field_type += FieldTypeFromDescriptor(parent, *desc.message_type()->field(0),
                                        packageless_type);
  field_type += ",";
  field_type += FieldTypeFromDescriptor(parent, *desc.message_type()->field(1),
                                        packageless_type);
  field_type += ">";
  return field_type;
}

std::unique_ptr<google::protobuf::Message> NormalizeOptionsMessage(
    const google::protobuf::DescriptorPool& pool,
    google::protobuf::DynamicMessageFactory* factory,
    const google::protobuf::Message& message) {
  const auto* option_descriptor =
      pool.FindMessageTypeByName(message.GetDescriptor()->full_name());
  if (!option_descriptor)
    return nullptr;

  std::unique_ptr<google::protobuf::Message> dynamic_options(
      factory->GetPrototype(option_descriptor)->New());
  PERFETTO_CHECK(dynamic_options->ParseFromString(message.SerializeAsString()));
  return dynamic_options;
}

std::vector<ProtoFile::Option> OptionsFromMessage(
    const google::protobuf::DescriptorPool& pool,
    const google::protobuf::Message& raw_message) {
  google::protobuf::DynamicMessageFactory factory;

  auto normalized = NormalizeOptionsMessage(pool, &factory, raw_message);
  const auto* message = normalized ? normalized.get() : &raw_message;
  const auto* reflection = message->GetReflection();

  std::vector<const google::protobuf::FieldDescriptor*> fields;
  reflection->ListFields(*message, &fields);

  std::vector<ProtoFile::Option> options;
  for (size_t i = 0; i < fields.size(); i++) {
    int count = 1;
    bool repeated = false;
    if (fields[i]->is_repeated()) {
      count = reflection->FieldSize(*message, fields[i]);
      repeated = true;
    }
    for (int j = 0; j < count; j++) {
      std::string name;
      if (fields[i]->is_extension()) {
        name = "(" + fields[i]->full_name() + ")";
      } else {
        name = fields[i]->name();
      }

      std::string fieldval;
      if (fields[i]->cpp_type() ==
          google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) {
        std::string tmp;
        google::protobuf::TextFormat::Printer printer;
        printer.PrintFieldValueToString(*message, fields[i], repeated ? j : -1,
                                        &tmp);
        fieldval.append("{\n");
        fieldval.append(tmp);
        fieldval.append("}");
      } else {
        google::protobuf::TextFormat::PrintFieldValueToString(
            *message, fields[i], repeated ? j : -1, &fieldval);
      }
      options.push_back(ProtoFile::Option{name, fieldval});
    }
  }
  return options;
}

template <typename Output, typename Descriptor>
Output InitFromDescriptor(const Descriptor& desc) {
  google::protobuf::SourceLocation source_loc;
  if (!desc.GetSourceLocation(&source_loc))
    return {};

  Output out;
  out.leading_comments = base::SplitString(source_loc.leading_comments, "\n");
  out.trailing_comments = base::SplitString(source_loc.trailing_comments, "\n");
  return out;
}

ProtoFile::Field FieldFromDescriptor(
    const google::protobuf::Descriptor& parent,
    const google::protobuf::FieldDescriptor& desc) {
  auto field = InitFromDescriptor<ProtoFile::Field>(desc);
  field.label = kLabelToName[desc.label()];
  field.packageless_type = FieldTypeFromDescriptor(parent, desc, true);
  field.type = FieldTypeFromDescriptor(parent, desc, false);
  field.name = desc.name();
  field.number = desc.number();
  field.options = OptionsFromMessage(*desc.file()->pool(), desc.options());
  return field;
}

ProtoFile::Enum::Value EnumValueFromDescriptor(
    const google::protobuf::EnumValueDescriptor& desc) {
  auto value = InitFromDescriptor<ProtoFile::Enum::Value>(desc);
  value.name = desc.name();
  value.number = desc.number();
  value.options = OptionsFromMessage(*desc.file()->pool(), desc.options());
  return value;
}

ProtoFile::Enum EnumFromDescriptor(
    const google::protobuf::EnumDescriptor& desc) {
  auto en = InitFromDescriptor<ProtoFile::Enum>(desc);
  en.name = desc.name();
  for (int i = 0; i < desc.value_count(); ++i) {
    en.values.emplace_back(EnumValueFromDescriptor(*desc.value(i)));
  }
  return en;
}

ProtoFile::Oneof OneOfFromDescriptor(
    const google::protobuf::Descriptor& parent,
    const google::protobuf::OneofDescriptor& desc) {
  auto oneof = InitFromDescriptor<ProtoFile::Oneof>(desc);
  oneof.name = desc.name();
  for (int i = 0; i < desc.field_count(); ++i) {
    oneof.fields.emplace_back(FieldFromDescriptor(parent, *desc.field(i)));
  }
  return oneof;
}

ProtoFile::Message MessageFromDescriptor(
    const google::protobuf::Descriptor& desc) {
  auto message = InitFromDescriptor<ProtoFile::Message>(desc);
  message.name = desc.name();
  for (int i = 0; i < desc.enum_type_count(); ++i) {
    message.enums.emplace_back(EnumFromDescriptor(*desc.enum_type(i)));
  }
  for (int i = 0; i < desc.nested_type_count(); ++i) {
    message.nested_messages.emplace_back(
        MessageFromDescriptor(*desc.nested_type(i)));
  }
  for (int i = 0; i < desc.oneof_decl_count(); ++i) {
    message.oneofs.emplace_back(OneOfFromDescriptor(desc, *desc.oneof_decl(i)));
  }
  for (int i = 0; i < desc.field_count(); ++i) {
    auto* field = desc.field(i);
    if (field->containing_oneof())
      continue;
    message.fields.emplace_back(FieldFromDescriptor(desc, *field));
  }
  return message;
}

}  // namespace

ProtoFile ProtoFileFromDescriptor(
    const google::protobuf::FileDescriptor& desc) {
  ProtoFile file;
  for (int i = 0; i < desc.enum_type_count(); ++i) {
    file.enums.push_back(EnumFromDescriptor(*desc.enum_type(i)));
  }
  for (int i = 0; i < desc.message_type_count(); ++i) {
    file.messages.push_back(MessageFromDescriptor(*desc.message_type(i)));
  }
  return file;
}

}  // namespace proto_merger
}  // namespace perfetto
