/*
 * Copyright (C) 2015 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 "event_attr.h"

#include <inttypes.h>
#include <stdio.h>
#include <string>
#include <unordered_map>

#include <android-base/logging.h>

#include "environment.h"
#include "event_type.h"
#include "utils.h"

static std::string BitsToString(const std::string& name, uint64_t bits,
                                const std::vector<std::pair<int, std::string>>& bit_names) {
  std::string result;
  for (auto& p : bit_names) {
    if (bits & p.first) {
      bits &= ~p.first;
      if (!result.empty()) {
        result += ", ";
      }
      result += p.second;
    }
  }
  if (bits != 0) {
    LOG(DEBUG) << "unknown " << name << " bits: " << std::hex << bits;
  }
  return result;
}

static std::string SampleTypeToString(uint64_t sample_type) {
  static std::vector<std::pair<int, std::string>> sample_type_names = {
      {PERF_SAMPLE_ADDR, "addr"},
      {PERF_SAMPLE_BRANCH_STACK, "branch_stack"},
      {PERF_SAMPLE_CALLCHAIN, "callchain"},
      {PERF_SAMPLE_CPU, "cpu"},
      {PERF_SAMPLE_ID, "id"},
      {PERF_SAMPLE_IP, "ip"},
      {PERF_SAMPLE_PERIOD, "period"},
      {PERF_SAMPLE_RAW, "raw"},
      {PERF_SAMPLE_READ, "read"},
      {PERF_SAMPLE_REGS_USER, "regs_user"},
      {PERF_SAMPLE_STACK_USER, "stack_user"},
      {PERF_SAMPLE_STREAM_ID, "stream_id"},
      {PERF_SAMPLE_TID, "tid"},
      {PERF_SAMPLE_TIME, "time"},
  };
  return BitsToString("sample_type", sample_type, sample_type_names);
}

static std::string ReadFormatToString(uint64_t read_format) {
  static std::vector<std::pair<int, std::string>> read_format_names = {
      {PERF_FORMAT_TOTAL_TIME_ENABLED, "total_time_enabled"},
      {PERF_FORMAT_TOTAL_TIME_RUNNING, "total_time_running"},
      {PERF_FORMAT_ID, "id"},
      {PERF_FORMAT_GROUP, "group"},
  };
  return BitsToString("read_format", read_format, read_format_names);
}

perf_event_attr CreateDefaultPerfEventAttr(const EventType& event_type) {
  perf_event_attr attr;
  memset(&attr, 0, sizeof(attr));
  attr.size = sizeof(perf_event_attr);
  attr.type = event_type.type;
  attr.config = event_type.config;
  attr.disabled = 0;
  // Changing read_format affects the layout of the data read from perf_event_file, namely
  // PerfCounter in event_fd.h.
  attr.read_format =
      PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING | PERF_FORMAT_ID;
  attr.sample_type |= PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_TIME | PERF_SAMPLE_PERIOD |
      PERF_SAMPLE_CPU | PERF_SAMPLE_ID;

  if (attr.type == PERF_TYPE_TRACEPOINT) {
    // Tracepoint information are stored in raw data in sample records.
    if (CanRecordRawData()) {
      attr.sample_type |= PERF_SAMPLE_RAW;
    }
  }
  return attr;
}

void DumpPerfEventAttr(const perf_event_attr& attr, size_t indent) {
  std::string event_name = GetEventNameByAttr(attr);
  PrintIndented(indent, "event_attr: for event type %s\n", event_name.c_str());

  PrintIndented(indent + 1, "type %u, size %u, config %llu\n", attr.type, attr.size, attr.config);

  if (attr.freq != 0) {
    PrintIndented(indent + 1, "sample_freq %llu\n", attr.sample_freq);
  } else {
    PrintIndented(indent + 1, "sample_period %llu\n", attr.sample_period);
  }

  PrintIndented(indent + 1, "sample_type (0x%llx) %s\n", attr.sample_type,
                SampleTypeToString(attr.sample_type).c_str());

  PrintIndented(indent + 1, "read_format (0x%llx) %s\n", attr.read_format,
                ReadFormatToString(attr.read_format).c_str());

  PrintIndented(indent + 1, "disabled %u, inherit %u, pinned %u, exclusive %u\n", attr.disabled,
                attr.inherit, attr.pinned, attr.exclusive);

  PrintIndented(indent + 1, "exclude_user %u, exclude_kernel %u, exclude_hv %u\n",
                attr.exclude_user, attr.exclude_kernel, attr.exclude_hv);

  PrintIndented(indent + 1, "exclude_idle %u, mmap %u, mmap2 %u, comm %u, freq %u\n",
                attr.exclude_idle, attr.mmap, attr.mmap2, attr.comm, attr.freq);

  PrintIndented(indent + 1, "inherit_stat %u, enable_on_exec %u, task %u\n", attr.inherit_stat,
                attr.enable_on_exec, attr.task);

  PrintIndented(indent + 1, "watermark %u, precise_ip %u, mmap_data %u\n", attr.watermark,
                attr.precise_ip, attr.mmap_data);

  PrintIndented(indent + 1, "sample_id_all %u, exclude_host %u, exclude_guest %u\n",
                attr.sample_id_all, attr.exclude_host, attr.exclude_guest);
  PrintIndented(indent + 1, "branch_sample_type 0x%" PRIx64 "\n", attr.branch_sample_type);
  PrintIndented(indent + 1, "exclude_callchain_kernel %u, exclude_callchain_user %u\n",
                attr.exclude_callchain_kernel, attr.exclude_callchain_user);
  PrintIndented(indent + 1, "sample_regs_user 0x%" PRIx64 "\n", attr.sample_regs_user);
  PrintIndented(indent + 1, "sample_stack_user 0x%" PRIx64 "\n", attr.sample_stack_user);
}

bool GetCommonEventIdPositionsForAttrs(std::vector<perf_event_attr>& attrs,
                                           size_t* event_id_pos_in_sample_records,
                                           size_t* event_id_reverse_pos_in_non_sample_records) {
  // When there are more than one perf_event_attrs, we need to read event id
  // in each record to decide current record should use which attr. So
  // we need to determine the event id position in a record here.
  std::vector<uint64_t> sample_types;
  for (const auto& attr : attrs) {
    sample_types.push_back(attr.sample_type);
  }
  // First determine event_id_pos_in_sample_records.
  // If PERF_SAMPLE_IDENTIFIER is enabled, it is just after perf_event_header.
  // If PERF_SAMPLE_ID is enabled, then PERF_SAMPLE_IDENTIFIER | IP | TID | TIME | ADDR
  // should also be the same.
  bool identifier_enabled = true;
  bool id_enabled = true;
  uint64_t flags_before_id_mask = PERF_SAMPLE_IDENTIFIER | PERF_SAMPLE_IP | PERF_SAMPLE_TID |
      PERF_SAMPLE_TIME | PERF_SAMPLE_ADDR;
  uint64_t flags_before_id = sample_types[0] & flags_before_id_mask;
  bool flags_before_id_are_the_same = true;
  for (auto type : sample_types) {
    identifier_enabled &= (type & PERF_SAMPLE_IDENTIFIER) != 0;
    id_enabled &= (type & PERF_SAMPLE_ID) != 0;
    flags_before_id_are_the_same &= (type & flags_before_id_mask) == flags_before_id;
  }
  if (identifier_enabled) {
    *event_id_pos_in_sample_records = sizeof(perf_event_header);
  } else if (id_enabled && flags_before_id_are_the_same) {
    uint64_t pos = sizeof(perf_event_header);
    while (flags_before_id != 0) {
      // Each flags takes 8 bytes in sample records.
      flags_before_id &= flags_before_id - 1;
      pos += 8;
    }
    *event_id_pos_in_sample_records = pos;
  } else {
    LOG(ERROR) << "perf_event_attrs don't have a common event id position in sample records";
    return false;
  }

  // Secondly determine event_id_reverse_pos_in_non_sample_record.
  // If sample_id_all is not enabled, there is no event id in non sample records.
  // If PERF_SAMPLE_IDENTIFIER is enabled, it is at the last 8 bytes of the record.
  // If PERF_SAMPLE_ID is enabled, then PERF_SAMPLE_IDENTIFIER | CPU | STREAM_ID should
  // also be the same.
  bool sample_id_all_enabled = true;
  for (const auto& attr : attrs) {
    if (attr.sample_id_all == 0) {
      sample_id_all_enabled = false;
    }
  }
  if (!sample_id_all_enabled) {
    LOG(ERROR) << "there are perf_event_attrs not enabling sample_id_all, so can't determine "
               << "perf_event_attr for non sample records";
    return false;
  }
  uint64_t flags_after_id_mask = PERF_SAMPLE_IDENTIFIER | PERF_SAMPLE_CPU | PERF_SAMPLE_STREAM_ID;
  uint64_t flags_after_id = sample_types[0] & flags_after_id_mask;
  bool flags_after_id_are_the_same = true;
  for (auto type : sample_types) {
    flags_after_id_are_the_same &= (type & flags_after_id_mask) == flags_after_id;
  }
  if (identifier_enabled) {
    *event_id_reverse_pos_in_non_sample_records = 8;
  } else if (id_enabled && flags_after_id_are_the_same) {
    uint64_t pos = 8;
    while (flags_after_id != 0) {
      // Each flag takes 8 bytes in sample_id of non sample records.
      flags_after_id &= flags_after_id - 1;
      pos += 8;
    }
    *event_id_reverse_pos_in_non_sample_records = pos;
  } else {
    LOG(ERROR) << "perf_event_attrs don't have a common event id reverse position in non sample records";
    return false;
  }
  return true;
}

bool IsTimestampSupported(const perf_event_attr& attr) {
  return attr.sample_id_all && (attr.sample_type & PERF_SAMPLE_TIME);
}

bool IsCpuSupported(const perf_event_attr& attr) {
  return attr.sample_id_all && (attr.sample_type & PERF_SAMPLE_CPU);
}

std::string GetEventNameByAttr(const perf_event_attr& attr) {
  for (const auto& event_type : GetAllEventTypes()) {
    if (event_type.type == attr.type && event_type.config == attr.config) {
      std::string name = event_type.name;
      if (attr.exclude_user && !attr.exclude_kernel) {
        name += ":k";
      } else if (attr.exclude_kernel && !attr.exclude_user) {
        name += ":u";
      }
      return name;
    }
  }
  return "unknown";
}
