/*
 * 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 "src/trace_processor/importers/proto/perf_sample_tracker.h"

#include <stdio.h>

#include <cinttypes>

#include "perfetto/ext/base/string_utils.h"
#include "src/trace_processor/importers/common/track_tracker.h"
#include "src/trace_processor/storage/trace_storage.h"
#include "src/trace_processor/types/trace_processor_context.h"

#include "protos/perfetto/common/perf_events.pbzero.h"
#include "protos/perfetto/trace/profiling/profile_packet.pbzero.h"
#include "protos/perfetto/trace/trace_packet_defaults.pbzero.h"

namespace perfetto {
namespace trace_processor {

namespace {
// Follow perf tool naming convention.
const char* StringifyCounter(int32_t counter) {
  using protos::pbzero::PerfEvents;
  switch (counter) {
    // software:
    case PerfEvents::SW_CPU_CLOCK:
      return "cpu-clock";
    case PerfEvents::SW_PAGE_FAULTS:
      return "page-faults";
    case PerfEvents::SW_TASK_CLOCK:
      return "task-clock";
    case PerfEvents::SW_CONTEXT_SWITCHES:
      return "context-switches";
    case PerfEvents::SW_CPU_MIGRATIONS:
      return "cpu-migrations";
    case PerfEvents::SW_PAGE_FAULTS_MIN:
      return "minor-faults";
    case PerfEvents::SW_PAGE_FAULTS_MAJ:
      return "major-faults";
    case PerfEvents::SW_ALIGNMENT_FAULTS:
      return "alignment-faults";
    case PerfEvents::SW_EMULATION_FAULTS:
      return "emulation-faults";
    case PerfEvents::SW_DUMMY:
      return "dummy";
    // hardware:
    case PerfEvents::HW_CPU_CYCLES:
      return "cpu-cycles";
    case PerfEvents::HW_INSTRUCTIONS:
      return "instructions";
    case PerfEvents::HW_CACHE_REFERENCES:
      return "cache-references";
    case PerfEvents::HW_CACHE_MISSES:
      return "cache-misses";
    case PerfEvents::HW_BRANCH_INSTRUCTIONS:
      return "branch-instructions";
    case PerfEvents::HW_BRANCH_MISSES:
      return "branch-misses";
    case PerfEvents::HW_BUS_CYCLES:
      return "bus-cycles";
    case PerfEvents::HW_STALLED_CYCLES_FRONTEND:
      return "stalled-cycles-frontend";
    case PerfEvents::HW_STALLED_CYCLES_BACKEND:
      return "stalled-cycles-backend";
    case PerfEvents::HW_REF_CPU_CYCLES:
      return "ref-cycles";

    default:
      break;
  }
  PERFETTO_DLOG("Unknown PerfEvents::Counter enum value");
  return "unknown";
}

StringId InternTimebaseCounterName(
    const protos::pbzero::PerfSampleDefaults::Decoder& perf_defaults,
    TraceProcessorContext* context) {
  using namespace protos::pbzero;
  PerfEvents::Timebase::Decoder timebase(perf_defaults.timebase());

  auto config_given_name = timebase.name();
  if (config_given_name.size > 0) {
    return context->storage->InternString(config_given_name);
  }
  if (timebase.has_counter()) {
    return context->storage->InternString(StringifyCounter(timebase.counter()));
  }
  if (timebase.has_tracepoint()) {
    PerfEvents::Tracepoint::Decoder tracepoint(timebase.tracepoint());
    return context->storage->InternString(tracepoint.name());
  }
  if (timebase.has_raw_event()) {
    PerfEvents::RawEvent::Decoder raw(timebase.raw_event());
    // This doesn't follow any pre-existing naming scheme, but aims to be a
    // short-enough default that is distinguishable.
    base::StackString<128> name(
        "raw.0x%" PRIx32 ".0x%" PRIx64 ".0x%" PRIx64 ".0x%" PRIx64, raw.type(),
        raw.config(), raw.config1(), raw.config2());
    return context->storage->InternString(name.string_view());
  }

  PERFETTO_DLOG("Could not name the perf timebase counter");
  return context->storage->InternString("unknown");
}
}  // namespace

PerfSampleTracker::SamplingStreamInfo PerfSampleTracker::GetSamplingStreamInfo(
    uint32_t seq_id,
    uint32_t cpu,
    protos::pbzero::TracePacketDefaults::Decoder* nullable_defaults) {
  using protos::pbzero::PerfSampleDefaults;

  auto seq_it = seq_state_.find(seq_id);
  if (seq_it == seq_state_.end()) {
    seq_it = seq_state_.emplace(seq_id, next_perf_session_id_++).first;
  }
  SequenceState* seq_state = &seq_it->second;
  uint32_t session_id = seq_state->perf_session_id;

  auto cpu_it = seq_state->per_cpu.find(cpu);
  if (cpu_it != seq_state->per_cpu.end())
    return {seq_state->perf_session_id, cpu_it->second.timebase_track_id};

  std::optional<PerfSampleDefaults::Decoder> perf_defaults;
  if (nullable_defaults && nullable_defaults->has_perf_sample_defaults()) {
    perf_defaults.emplace(nullable_defaults->perf_sample_defaults());
  }

  StringId name_id = kNullStringId;
  if (perf_defaults.has_value()) {
    name_id = InternTimebaseCounterName(perf_defaults.value(), context_);
  } else {
    // No defaults means legacy producer implementation, assume default timebase
    // of per-cpu timer. This means either an Android R or early S build.
    name_id = context_->storage->InternString(
        StringifyCounter(protos::pbzero::PerfEvents::SW_CPU_CLOCK));
  }

  TrackId timebase_track_id = context_->track_tracker->CreatePerfCounterTrack(
      name_id, session_id, cpu, /*is_timebase=*/true);

  seq_state->per_cpu.emplace(cpu, timebase_track_id);

  // If the config requested process sharding, record in the stats table which
  // shard was chosen for the trace. It should be the same choice for all data
  // sources within one trace, but for consistency with other stats we put an
  // entry per data source (i.e. |perf_session_id|, not to be confused with the
  // tracing session).
  if (perf_defaults.has_value() && perf_defaults->process_shard_count() > 0) {
    context_->storage->SetIndexedStats(
        stats::perf_process_shard_count, static_cast<int>(session_id),
        static_cast<int64_t>(perf_defaults->process_shard_count()));
    context_->storage->SetIndexedStats(
        stats::perf_chosen_process_shard, static_cast<int>(session_id),
        static_cast<int64_t>(perf_defaults->chosen_process_shard()));
  }

  return {session_id, timebase_track_id};
}

}  // namespace trace_processor
}  // namespace perfetto
