/*
 * 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_serializer.h"

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

namespace perfetto {
namespace proto_merger {
namespace {

std::string DeletedComment(const std::string& prefix) {
  std::string output;
  output += "\n";
  output += prefix + "  //\n";
  output += prefix;
  output +=
      "  // The following enums/messages/fields are not present upstream\n";
  output += prefix + "  //\n";
  return output;
}

std::string SerializeComments(const std::string& prefix,
                              const std::vector<std::string>& lines) {
  std::string output;
  for (const auto& line : lines) {
    output.append(prefix);
    output.append("//");
    output.append(line);
    output.append("\n");
  }
  return output;
}

std::string SerializeLeadingComments(const std::string& prefix,
                                     const ProtoFile::Member& member,
                                     bool prefix_newline_if_comment = true) {
  if (member.leading_comments.empty())
    return "";

  std::string output;
  if (prefix_newline_if_comment) {
    output += "\n";
  }
  output += SerializeComments(prefix, member.leading_comments);
  return output;
}

std::string SerializeTrailingComments(const std::string& prefix,
                                      const ProtoFile::Member& member) {
  return SerializeComments(prefix, member.trailing_comments);
}

std::string SerializeOptions(const std::vector<ProtoFile::Option>& options) {
  if (options.empty())
    return "";

  std::string output;
  output += " [";
  for (const auto& option : options) {
    output += option.key + " = " + option.value;
  }
  output += "]";
  return output;
}

std::string SerializeEnumValue(size_t indent,
                               const ProtoFile::Enum::Value& value) {
  std::string prefix(indent * 2, ' ');

  std::string output;
  output += SerializeLeadingComments(prefix, value, false);

  output += prefix + value.name + " = " + std::to_string(value.number);
  output += SerializeOptions(value.options);
  output += ";\n";

  output += SerializeTrailingComments(prefix, value);
  return output;
}

std::string SerializeEnum(size_t indent, const ProtoFile::Enum& en) {
  std::string prefix(indent * 2, ' ');
  ++indent;

  std::string output;
  output += SerializeLeadingComments(prefix, en);

  output += prefix + "enum " + en.name + " {\n";
  for (const auto& value : en.values) {
    output += SerializeEnumValue(indent, value);
  }
  output += prefix + "}\n";

  output += SerializeTrailingComments(prefix, en);
  return output;
}

std::string SerializeField(size_t indent,
                           const ProtoFile::Field& field,
                           bool write_label) {
  std::string prefix(indent * 2, ' ');

  std::string output;
  output += SerializeLeadingComments(prefix, field);

  std::string label;
  if (write_label) {
    label = field.label + " ";
  }
  output += prefix + label + field.type + " " + field.name + " = " +
            std::to_string(field.number);

  output += SerializeOptions(field.options);
  output += ";\n";

  output += SerializeTrailingComments(prefix, field);
  return output;
}

std::string SerializeOneof(size_t indent, const ProtoFile::Oneof& oneof) {
  std::string prefix(indent * 2, ' ');
  ++indent;

  std::string output;
  output += SerializeLeadingComments(prefix, oneof);

  output += prefix + "oneof " + oneof.name + " {\n";
  for (const auto& field : oneof.fields) {
    output += SerializeField(indent, field, false);
  }
  output += prefix + "}\n";

  output += SerializeTrailingComments(prefix, oneof);
  return output;
}

std::string SerializeMessage(size_t indent, const ProtoFile::Message& message) {
  std::string prefix(indent * 2, ' ');
  ++indent;

  std::string output;
  output += SerializeLeadingComments(prefix, message);

  output += prefix + "message " + message.name + " {\n";
  for (const auto& en : message.enums) {
    output += SerializeEnum(indent, en);
  }
  for (const auto& nested : message.nested_messages) {
    output += SerializeMessage(indent, nested);
  }
  for (const auto& oneof : message.oneofs) {
    output += SerializeOneof(indent, oneof);
  }
  for (const auto& field : message.fields) {
    output += SerializeField(indent, field, true);
  }

  if (!message.deleted_enums.empty() || !message.deleted_fields.empty() ||
      !message.deleted_nested_messages.empty() ||
      !message.deleted_oneofs.empty()) {
    output += DeletedComment(prefix);
    for (const auto& en : message.deleted_enums) {
      output += SerializeEnum(indent, en);
    }
    for (const auto& nested : message.deleted_nested_messages) {
      output += SerializeMessage(indent, nested);
    }
    for (const auto& oneof : message.deleted_oneofs) {
      output += SerializeOneof(indent, oneof);
    }
    for (const auto& field : message.deleted_fields) {
      output += SerializeField(indent, field, true);
    }
  }

  output += prefix + "}\n";

  output += SerializeTrailingComments(prefix, message);
  return output;
}

}  // namespace

std::string ProtoFileToDotProto(const ProtoFile& proto_file) {
  std::string output;
  for (const auto& en : proto_file.enums) {
    output += SerializeEnum(0, en);
  }
  for (const auto& message : proto_file.messages) {
    output += SerializeMessage(0, message);
  }

  if (!proto_file.deleted_enums.empty() ||
      !proto_file.deleted_messages.empty()) {
    output += DeletedComment("");

    for (const auto& en : proto_file.deleted_enums) {
      output += SerializeEnum(0, en);
    }
    for (const auto& nested : proto_file.deleted_messages) {
      output += SerializeMessage(0, nested);
    }
  }
  return output;
}

}  // namespace proto_merger
}  // namespace perfetto
