/*
 * Copyright (C) 2018 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/ftrace_proto_gen/ftrace_descriptor_gen.h"

namespace perfetto {

void GenerateFtraceDescriptors(
    const google::protobuf::DescriptorPool& descriptor_pool,
    std::ostream* fout) {
  const google::protobuf::Descriptor* ftrace_event =
      descriptor_pool.FindMessageTypeByName("perfetto.protos.FtraceEvent");
  const google::protobuf::OneofDescriptor* one_of_event =
      ftrace_event->FindOneofByName("event");

  // Find max id for any ftrace event.
  int max_id = 0;
  for (int i = 0; i < one_of_event->field_count(); i++)
    max_id = std::max(max_id, one_of_event->field(i)->number());

  *fout << "// Autogenerated by:\n";
  *fout << std::string("// ") + __FILE__ + "\n";
  *fout << "// Do not edit.\n";
  *fout << R"(
#include "src/trace_processor/importers/ftrace/ftrace_descriptors.h"

namespace perfetto {
namespace trace_processor {
namespace {

std::array<MessageDescriptor,
  )";
  *fout << std::to_string(max_id + 1) + "> descriptors{{";

  for (int i = 0; i <= max_id; i++) {
    const google::protobuf::FieldDescriptor* event =
        ftrace_event->FindFieldByNumber(i);
    // Skip events that don't exist or are not messages. (Proxy for events)
    if (!event ||
        event->type() != google::protobuf::FieldDescriptor::TYPE_MESSAGE) {
      *fout << "{nullptr, 0, {}},";
      continue;
    }

    const auto* event_descriptor = event->message_type();

    // Find the max field id in the event.
    int max_field_id = 0;
    for (int j = 0; j < event_descriptor->field_count(); j++)
      max_field_id =
          std::max(max_field_id, event_descriptor->field(j)->number());

    *fout << "{\"" + event->name() + "\", " << max_field_id << ", "
          << "{";

    for (int j = 0; j <= max_field_id; j++) {
      const auto* field = event_descriptor->FindFieldByNumber(j);
      // Skip fields that don't exist or are nested messages.
      if (!field ||
          field->type() == google::protobuf::FieldDescriptor::TYPE_MESSAGE) {
        *fout << "{},";
        continue;
      }
      ProtoType type = ProtoType::FromDescriptor(field->type());
      *fout << "{\"" + field->name() + "\", ProtoSchemaType::k" +
                   ToCamelCase(type.ToString()) + "},";
    }
    *fout << "},\n},";
  }
  *fout << "}};\n";
  *fout << R"(
} // namespace

MessageDescriptor* GetMessageDescriptorForId(size_t id) {
  PERFETTO_CHECK(id < descriptors.size());
  return &descriptors[id];
}

size_t GetDescriptorsSize() {
  return descriptors.size();
}
  )";
  *fout << "} // namespace trace_processor\n} // namespace perfetto\n";
}

}  // namespace perfetto
