/*
 * Copyright (C) 2020 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 "src/trace_processor/tp_metatrace.h"

namespace perfetto {
namespace trace_processor {
namespace metatrace {

namespace {

using ProtoEnum = protos::pbzero::MetatraceCategories;
ProtoEnum MetatraceCategoriesToProtoEnum(MetatraceCategories categories) {
  switch (categories) {
    case MetatraceCategories::TOPLEVEL:
      return ProtoEnum::TOPLEVEL;
    case MetatraceCategories::FUNCTION:
      return ProtoEnum::FUNCTION;
    case MetatraceCategories::QUERY:
      return ProtoEnum::QUERY;
    case MetatraceCategories::ALL:
      return ProtoEnum::ALL;
    case MetatraceCategories::NONE:
      return ProtoEnum::NONE;
  }
  return ProtoEnum::NONE;
}

}  // namespace

Category g_enabled_categories = Category::NONE;

void Enable(MetatraceConfig config) {
  g_enabled_categories = MetatraceCategoriesToProtoEnum(config.categories);
  if (config.override_buffer_size) {
    RingBuffer::GetInstance()->Resize(config.override_buffer_size);
  }
}

void DisableAndReadBuffer(std::function<void(Record*)> fn) {
  g_enabled_categories = Category::NONE;
  if (!fn)
    return;
  RingBuffer::GetInstance()->ReadAll(fn);
}

RingBuffer::RingBuffer() : data_(kDefaultCapacity) {
  static_assert((kDefaultCapacity & (kDefaultCapacity - 1)) == 0,
                "Capacity should be a power of 2");
}

void RingBuffer::Resize(size_t requested_capacity) {
  size_t actual_capacity = 1;
  while (actual_capacity < requested_capacity)
    actual_capacity <<= 1;
  data_.resize(actual_capacity);
  start_idx_ = 0;
  write_idx_ = 0;
}

void RingBuffer::ReadAll(std::function<void(Record*)> fn) {
  // Mark as reading so we don't get reentrancy in obtaining new
  // trace events.
  is_reading_ = true;

  uint64_t start = (write_idx_ - start_idx_) < data_.size()
                       ? start_idx_
                       : write_idx_ - data_.size();
  uint64_t end = write_idx_;

  // Increment the write index by kCapacity + 1. This ensures that if
  // ScopedEntry is destoryed in |fn| below, we won't get overwrites
  // while reading the buffer.
  // This works because of the logic in ~ScopedEntry and
  // RingBuffer::HasOverwritten which ensures that we don't overwrite entries
  // more than kCapcity elements in the past.
  write_idx_ += data_.size() + 1;

  for (uint64_t i = start; i < end; ++i) {
    Record* record = At(i);

    // If the slice was unfinished for some reason, don't emit it.
    if (record->duration_ns != 0) {
      fn(record);
    }
  }

  // Ensure that the start pointer is updated to the write pointer.
  start_idx_ = write_idx_;

  // Remove the reading marker.
  is_reading_ = false;
}

}  // namespace metatrace
}  // namespace trace_processor
}  // namespace perfetto
