// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "garnet/bin/cpuperf_provider/importer.h"

#include <assert.h>
#include <inttypes.h>
#include <atomic>

#include <src/lib/fxl/logging.h>
#include <src/lib/fxl/strings/string_printf.h>
#include <src/lib/fxl/time/time_point.h>
#include <zircon/syscalls.h>

#include "garnet/bin/cpuperf_provider/categories.h"
#include "garnet/lib/perfmon/reader.h"
#include "garnet/lib/perfmon/writer.h"

namespace cpuperf_provider {

// Mock process for cpus. The infrastructure only supports processes and
// threads.
constexpr zx_koid_t kCpuProcess = 1u;

Importer::Importer(trace_context_t* context, const TraceConfig* trace_config,
                   trace_ticks_t start_time, trace_ticks_t stop_time)
#define MAKE_STRING(literal) trace_context_make_registered_string_literal(context, literal)
    : context_(context),
      trace_config_(trace_config),
      start_time_(start_time),
      stop_time_(stop_time),
      cpu_string_ref_(MAKE_STRING("cpu")),
      cpuperf_category_ref_(MAKE_STRING("cpu:perf")),
      count_name_ref_(MAKE_STRING("count")),
      value_name_ref_(MAKE_STRING("value")),
      rate_name_ref_(MAKE_STRING("rate")),
      aspace_name_ref_(MAKE_STRING("aspace")),
      pc_name_ref_(MAKE_STRING("pc")) {
  for (unsigned cpu = 0; cpu < countof(cpu_thread_refs_); ++cpu) {
    // +1 because index thread refs start at 1
    trace_thread_index_t index = cpu + 1;
    cpu_thread_refs_[cpu] = trace_make_indexed_thread_ref(index);
    // Note: Thread ids of zero are invalid. We use "thread 0" (aka cpu 0)
    // for system-wide events.
    trace_context_write_thread_record(context, index, kCpuProcess, cpu);
    if (cpu == 0) {
      cpu_name_refs_[0] = trace_context_make_registered_string_literal(context, "system");
    } else {
      std::string name = fxl::StringPrintf("cpu%u", cpu - 1);
      cpu_name_refs_[cpu] =
          trace_context_make_registered_string_copy(context, name.c_str(), name.size());
    }
    // TODO(dje): In time emit "cpuN" for thread names, but it won't do any
    // good at the moment as we use "Count" records which ignore the thread.
  }
#undef MAKE_STRING
}

Importer::~Importer() = default;

bool Importer::Import(perfmon::Reader& reader, const perfmon::Config& perfmon_config) {
  trace_context_write_process_info_record(context_, kCpuProcess, &cpu_string_ref_);

  auto start = fxl::TimePoint::Now();

  uint32_t record_count = ImportRecords(reader, perfmon_config);

  FXL_LOG(INFO) << "Import of " << record_count << " cpu perf records took "
                << (fxl::TimePoint::Now() - start).ToMicroseconds() << " us";

  return true;
}

uint64_t Importer::ImportRecords(perfmon::Reader& reader, const perfmon::Config& perfmon_config) {
  EventTracker event_data(start_time_);
  uint32_t record_count = 0;
  // Only print these warnings once, and then again at the end with
  // the total count. We don't want a broken trace to flood the screen
  // with messages.
  uint32_t printed_zero_period_warning_count = 0;
  uint32_t printed_old_time_warning_count = 0;
  uint32_t printed_late_record_warning_count = 0;

  uint32_t cpu;
  perfmon::SampleRecord record;

  uint64_t sample_rate = trace_config_->sample_rate();
  bool is_tally_mode = sample_rate == 0;
  trace_ticks_t current_time = reader.time();

  while (reader.ReadNextRecord(&cpu, &record) == perfmon::ReaderStatus::kOk) {
    FXL_DCHECK(cpu < kMaxNumCpus);
    perfmon::EventId event_id = record.event();
    uint64_t ticks_per_second = reader.ticks_per_second();

    // There can be millions of records. This log message is useful for small
    // test runs, but otherwise is too painful. The verbosity level is chosen
    // to recognize that.
    FXL_VLOG(10) << fxl::StringPrintf("Import: cpu=%u, event=0x%x, time=%" PRIu64, cpu, event_id,
                                      current_time);

    if (record.type() == perfmon::kRecordTypeTime) {
      current_time = reader.time();
      if (event_id == perfmon::kEventIdNone) {
        // This is just a time update, not a combined time+tick record.
        ++record_count;
        continue;
      }
    }

    // Get the time we last saw this event.
    trace_ticks_t prev_time = event_data.GetTime(cpu, event_id);

    if (current_time < prev_time) {
      if (printed_old_time_warning_count == 0) {
        FXL_LOG(WARNING) << "cpu " << cpu << ": record time " << current_time << " < previous time "
                         << prev_time << " (further such warnings are omitted)";
      }
      ++printed_old_time_warning_count;
    } else if (current_time == prev_time) {
      if (printed_zero_period_warning_count == 0) {
        FXL_LOG(WARNING) << "cpu " << cpu << ": empty interval at time " << current_time
                         << " (further such warnings are omitted)";
      }
      ++printed_zero_period_warning_count;
    } else if (current_time > stop_time_) {
      if (printed_late_record_warning_count == 0) {
        FXL_LOG(WARNING) << "Record has time > stop_time: " << current_time
                         << " (further such warnings are omitted)";
      }
      ++printed_late_record_warning_count;
    } else {
      switch (record.type()) {
        case perfmon::kRecordTypeTime:
          FXL_DCHECK(event_id != perfmon::kEventIdNone);
          // fall through
        case perfmon::kRecordTypeTick:
          if (is_tally_mode) {
            event_data.AccumulateCount(cpu, event_id, sample_rate);
          } else {
            ImportSampleRecord(cpu, record, prev_time, current_time, ticks_per_second, sample_rate);
          }
          break;
        case perfmon::kRecordTypeCount:
          if (is_tally_mode) {
            event_data.AccumulateCount(cpu, event_id, record.count->count);
          } else {
            ImportSampleRecord(cpu, record, prev_time, current_time, ticks_per_second,
                               record.count->count);
          }
          break;
        case perfmon::kRecordTypeValue:
          if (is_tally_mode) {
            event_data.UpdateValue(cpu, event_id, record.value->value);
          } else {
            ImportSampleRecord(cpu, record, prev_time, current_time, ticks_per_second,
                               record.value->value);
          }
          break;
        case perfmon::kRecordTypePc:
          if (!is_tally_mode) {
            ImportSampleRecord(cpu, record, prev_time, current_time, ticks_per_second, sample_rate);
          }
          break;
        case perfmon::kRecordTypeLastBranch:
          if (!is_tally_mode) {
            EmitLastBranchRecordBlob(cpu, record, current_time);
          }
          break;
        default:
          // The reader shouldn't be returning unknown records.
          FXL_NOTREACHED();
          break;
      }
    }

    event_data.UpdateTime(cpu, event_id, current_time);
    ++record_count;
  }

  if (is_tally_mode) {
    EmitTallyCounts(reader, perfmon_config, event_data);
  }

  if (printed_old_time_warning_count > 0) {
    FXL_LOG(WARNING) << printed_old_time_warning_count
                     << " total occurrences of records going back in time";
  }
  if (printed_zero_period_warning_count > 0) {
    FXL_LOG(WARNING) << printed_zero_period_warning_count
                     << " total occurrences of records with an empty interval";
  }
  if (printed_late_record_warning_count > 0) {
    FXL_LOG(WARNING) << printed_late_record_warning_count
                     << " total occurrences of records with late times";
  }

  return record_count;
}

void Importer::ImportSampleRecord(trace_cpu_number_t cpu, const perfmon::SampleRecord& record,
                                  trace_ticks_t previous_time, trace_ticks_t current_time,
                                  uint64_t ticks_per_second, uint64_t event_value) {
  perfmon::EventId event_id = record.event();
  const perfmon::EventDetails* details;
  // Note: Errors here are generally rare, so at present we don't get clever
  // with minimizing the noise.
  if (trace_config_->model_event_manager()->EventIdToEventDetails(event_id, &details)) {
    EmitSampleRecord(cpu, details, record, previous_time, current_time, ticks_per_second,
                     event_value);
  } else {
    FXL_LOG(ERROR) << "Invalid event id: " << event_id;
  }
}

void Importer::EmitSampleRecord(trace_cpu_number_t cpu, const perfmon::EventDetails* details,
                                const perfmon::SampleRecord& record, trace_ticks_t start_time,
                                trace_ticks_t end_time, uint64_t ticks_per_second, uint64_t value) {
  FXL_DCHECK(start_time < end_time);
  trace_thread_ref_t thread_ref{GetCpuThreadRef(cpu, details->id)};
  trace_string_ref_t name_ref{
      trace_context_make_registered_string_literal(context_, details->name)};
#if 0
  // Count records are "process wide" so we need some way to distinguish
  // each cpu. Thus while it might be nice to use this for "id" we don't.
  uint64_t id = record.event();
#else
  // Add one as zero doesn't get printed.
  uint64_t id = cpu + 1;
#endif

  // While the count of events is cumulative, it's more useful to report some
  // measure that's useful within each time period. E.g., a rate.
  uint64_t interval_ticks = end_time - start_time;
  FXL_DCHECK(interval_ticks > 0);
  double rate_per_second = 0;
  // rate_per_second = value / (interval_ticks / ticks_per_second)
  // ticks_per_second could be zero if there's bad data in the buffer.
  // Don't crash because of it. If it's zero just punt and compute the rate
  // per tick.
  // TODO(dje): Perhaps the rate calculation should be done in the report
  // generator, but it's done this way so that catapult reports in chrome
  // are usable. Maybe add a new phase type to the catapult format?
  rate_per_second = static_cast<double>(value) / interval_ticks;
  if (ticks_per_second != 0) {
    rate_per_second *= ticks_per_second;
  }

  trace_arg_t args[3];
  size_t n_args;
  switch (record.type()) {
    case perfmon::kRecordTypeTick:
      args[0] = {trace_make_arg(rate_name_ref_, trace_make_double_arg_value(rate_per_second))};
      n_args = 1;
      break;
    case perfmon::kRecordTypeCount:
      args[0] = {trace_make_arg(rate_name_ref_, trace_make_double_arg_value(rate_per_second))};
      n_args = 1;
      break;
    case perfmon::kRecordTypeValue:
      // We somehow need to mark the value as not being a count. This is
      // important for some consumers to guide how to print the value.
      // Do this by using a different name for the value.
      args[0] = {trace_make_arg(value_name_ref_, trace_make_uint64_arg_value(value))};
      n_args = 1;
      break;
    case perfmon::kRecordTypePc:
      args[1] = {trace_make_arg(aspace_name_ref_, trace_make_uint64_arg_value(record.pc->aspace))};
      args[2] = {trace_make_arg(pc_name_ref_, trace_make_uint64_arg_value(record.pc->pc))};
      n_args = 3;
      break;
    default:
      FXL_NOTREACHED();
      return;
  }

#if 0
  // TODO(dje): This is a failed experiment to use something other than
  // counters. It is kept, for now, to allow easy further experimentation.
  trace_context_write_async_begin_event_record(
      context_, start_time,
      &thread_ref, &cpuperf_category_ref_, &name_ref,
      id, nullptr, 0);
  trace_context_write_async_end_event_record(
      context_, end_time,
      &thread_ref, &cpuperf_category_ref_, &name_ref,
      id, &args[0], n_args);
#else
  // Chrome interprets the timestamp we give it as the start of the
  // interval, which for a count makes sense: this is the value of the count
  // from this point on until the next count record. We're abusing this record
  // type to display a rate.
  trace_context_write_counter_event_record(context_, start_time, &thread_ref,
                                           &cpuperf_category_ref_, &name_ref, id, &args[0], n_args);
#endif
}

void Importer::EmitLastBranchRecordBlob(trace_cpu_number_t cpu, const perfmon::SampleRecord& record,
                                        trace_ticks_t time) {
  // Use the cpu's name as the blob's name.
  auto cpu_name_ref{GetCpuNameRef(cpu)};
  uint16_t num_branches = record.last_branch->num_branches;
  size_t size = perfmon::LastBranchRecordBlobSize(num_branches);
  void* ptr = trace_context_begin_write_blob_record(context_, TRACE_BLOB_TYPE_LAST_BRANCH,
                                                    &cpu_name_ref, size);
  if (ptr) {
    auto rec = reinterpret_cast<perfmon::LastBranchRecordBlob*>(ptr);
    rec->cpu = cpu;
    rec->num_branches = record.last_branch->num_branches;
    rec->reserved = 0;
    rec->event_time = time;
    rec->aspace = record.last_branch->aspace;
    static_assert(sizeof(rec->branches[0]) == sizeof(record.last_branch->branches[0]), "");
    memcpy(&rec->branches[0], &record.last_branch->branches[0],
           num_branches * sizeof(record.last_branch->branches[0]));
  }
}

// Chrome interprets the timestamp we give Count records as the start
// of the interval with that count, which for a count makes sense: this is
// the value of the count from this point on until the next count record.
// But if we emit a value of zero at the start (or don't emit any initial
// value at all) Chrome shows the entire trace of having the value zero and
// the count record at the end of the interval is very hard to see.
// OTOH the data is correct, it's just the display that's hard to read.
// Text display of the results is unaffected.
// One important reason for providing a value at the start is because there's
// currently no other way to communicate the start time of the trace in a
// json output file, and thus there would otherwise be no way for the
// report printer to know the duration over which the count was collected.
void Importer::EmitTallyCounts(perfmon::Reader& reader, const perfmon::Config& perfmon_config,
                               const EventTracker& event_data) {
  unsigned num_cpus = zx_system_get_num_cpus();

  for (unsigned cpu = 0; cpu < num_cpus; ++cpu) {
    perfmon_config.IterateOverEvents(
        [this, &event_data, &cpu](const perfmon::Config::EventConfig& event) {
          perfmon::EventId event_id = event.event;
          if (event_data.HaveValue(cpu, event_id)) {
            uint64_t value = event_data.GetCountOrValue(cpu, event_id);
            if (event_data.IsValue(cpu, event_id)) {
              EmitTallyRecord(cpu, event_id, stop_time_, true, value);
            } else {
              EmitTallyRecord(cpu, event_id, start_time_, false, 0);
              EmitTallyRecord(cpu, event_id, stop_time_, false, value);
            }
          }
        });
  }
}

void Importer::EmitTallyRecord(trace_cpu_number_t cpu, perfmon::EventId event_id,
                               trace_ticks_t time, bool is_value, uint64_t value) {
  trace_thread_ref_t thread_ref{GetCpuThreadRef(cpu, event_id)};
  trace_arg_t args[1] = {
      {trace_make_arg(is_value ? value_name_ref_ : count_name_ref_,
                      trace_make_uint64_arg_value(value))},
  };
  const perfmon::EventDetails* details;
  if (trace_config_->model_event_manager()->EventIdToEventDetails(event_id, &details)) {
    trace_string_ref_t name_ref{
        trace_context_make_registered_string_literal(context_, details->name)};
    trace_context_write_counter_event_record(context_, time, &thread_ref, &cpuperf_category_ref_,
                                             &name_ref, event_id, &args[0], countof(args));
  } else {
    FXL_LOG(WARNING) << "Invalid event id: " << event_id;
  }
}

trace_string_ref_t Importer::GetCpuNameRef(trace_cpu_number_t cpu) {
  FXL_DCHECK(cpu < countof(cpu_name_refs_));
  return cpu_name_refs_[cpu + 1];
}

trace_thread_ref_t Importer::GetCpuThreadRef(trace_cpu_number_t cpu, perfmon::EventId id) {
  FXL_DCHECK(cpu < countof(cpu_thread_refs_));
  // TODO(dje): Misc events are currently all system-wide, not attached
  // to any specific cpu. That won't always be the case.
  if (perfmon::GetEventIdGroup(id) == perfmon::kGroupMisc)
    cpu = 0;
  else
    ++cpu;
  return cpu_thread_refs_[cpu];
}

}  // namespace cpuperf_provider
