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

#include <utility>

#include "base/logging.h"
#include "proto_translation_table.h"

#include "protos/ftrace/ftrace_event.pbzero.h"
#include "protos/ftrace/print.pbzero.h"
#include "protos/ftrace/sched_switch.pbzero.h"

#include "protos/ftrace/ftrace_event_bundle.pbzero.h"

namespace perfetto {

namespace {

using BundleHandle =
    protozero::ProtoZeroMessageHandle<protos::pbzero::FtraceEventBundle>;

const std::vector<bool> BuildEnabledVector(const ProtoTranslationTable& table,
                                           const std::set<std::string>& names) {
  std::vector<bool> enabled(table.largest_id() + 1);
  for (const std::string& name : names) {
    const ProtoTranslationTable::Event* event = table.GetEventByName(name);
    if (!event)
      continue;
    enabled[event->ftrace_event_id] = true;
  }
  return enabled;
}

// For further documentation of these constants see the kernel source:
// linux/include/linux/ring_buffer.h
// Some information about the values of these constants are exposed to user
// space at: /sys/kernel/debug/tracing/events/header_event
const uint32_t kTypeDataTypeLengthMax = 28;
const uint32_t kTypePadding = 29;
const uint32_t kTypeTimeExtend = 30;
const uint32_t kTypeTimeStamp = 31;

const size_t kPageSize = 4096;

struct PageHeader {
  uint64_t timestamp;
  uint32_t size;
  uint32_t : 24;
  uint32_t overwrite : 8;
};

struct EventHeader {
  uint32_t type_or_length : 5;
  uint32_t time_delta : 27;
};

struct TimeStamp {
  uint64_t tv_nsec;
  uint64_t tv_sec;
};

}  // namespace

EventFilter::EventFilter(const ProtoTranslationTable& table,
                         std::set<std::string> names)
    : enabled_ids_(BuildEnabledVector(table, names)),
      enabled_names_(std::move(names)) {}
EventFilter::~EventFilter() = default;

CpuReader::CpuReader(const ProtoTranslationTable* table,
                     size_t cpu,
                     base::ScopedFile fd)
    : table_(table), cpu_(cpu), fd_(std::move(fd)) {}

int CpuReader::GetFileDescriptor() {
  return fd_.get();
}

bool CpuReader::Drain(const std::array<const EventFilter*, kMaxSinks>& filters,
                      const std::array<BundleHandle, kMaxSinks>& bundles) {
  if (!fd_)
    return false;

  uint8_t* buffer = GetBuffer();
  // TOOD(hjd): One read() per page may be too many.
  long bytes = PERFETTO_EINTR(read(fd_.get(), buffer, kPageSize));
  if (bytes == -1 || bytes == 0)
    return false;
  PERFETTO_CHECK(bytes <= kPageSize);

  for (size_t i = 0; i < kMaxSinks; i++) {
    if (!filters[i])
      break;
    bool result =
        ParsePage(cpu_, buffer, bytes, filters[i], &*bundles[i], table_);
    PERFETTO_DCHECK(result);
  }
  return true;
}

CpuReader::~CpuReader() = default;

uint8_t* CpuReader::GetBuffer() {
  // TODO(primiano): Guard against overflows, like BufferedFrameDeserializer.
  if (!buffer_)
    buffer_ = std::unique_ptr<uint8_t[]>(new uint8_t[kPageSize]);
  return buffer_.get();
}

// The structure of a raw trace buffer page is as follows:
// First a page header:
//   8 bytes of timestamp
//   8 bytes of page length TODO(hjd): other fields also defined here?
// // TODO(hjd): Document rest of format.
// Some information about the layout of the page header is available in user
// space at: /sys/kernel/debug/tracing/events/header_event
// This method is deliberately static so it can be tested independently.
bool CpuReader::ParsePage(size_t cpu,
                          const uint8_t* ptr,
                          size_t size,
                          const EventFilter* filter,
                          protos::pbzero::FtraceEventBundle* bundle,
                          const ProtoTranslationTable* table) {
  // TODO(hjd): Remove when the generic parser comes in.
  const size_t print_id = table->GetEventByName("print")->ftrace_event_id;
  const size_t sched_switch_id =
      table->GetEventByName("sched_switch")->ftrace_event_id;

  const uint8_t* const start_of_page = ptr;
  const uint8_t* const end_of_page = ptr + size;

  bundle->set_cpu(cpu);

  (void)start_of_page;

  // TODO(hjd): Read this format dynamically?
  PageHeader page_header;
  if (!ReadAndAdvance(&ptr, end_of_page, &page_header))
    return false;

  const uint8_t* const end = ptr + page_header.size;
  if (end > end_of_page)
    return false;

  while (ptr < end) {
    EventHeader event_header;
    if (!ReadAndAdvance(&ptr, end, &event_header))
      return false;
    switch (event_header.type_or_length) {
      case kTypePadding: {
        // Left over page padding or discarded event.
        if (event_header.time_delta == 0) {
          // TODO(hjd): Look at the next few bytes for read size;
          PERFETTO_CHECK(false);  // TODO(hjd): Handle
        }
        uint32_t length;
        if (!ReadAndAdvance<uint32_t>(&ptr, end, &length))
          return false;
        ptr += length;
        break;
      }
      case kTypeTimeExtend: {
        // Extend the time delta.
        uint32_t time_delta_ext;
        if (!ReadAndAdvance<uint32_t>(&ptr, end, &time_delta_ext))
          return false;
        (void)time_delta_ext;
        // TODO(hjd): Handle.
        break;
      }
      case kTypeTimeStamp: {
        // Sync time stamp with external clock.
        TimeStamp time_stamp;
        if (!ReadAndAdvance<TimeStamp>(&ptr, end, &time_stamp))
          return false;
        // TODO(hjd): Handle.
        break;
      }
      // Data record:
      default: {
        PERFETTO_CHECK(event_header.type_or_length <= kTypeDataTypeLengthMax);
        // type_or_length is <=28 so it represents the length of a data record.
        if (event_header.type_or_length == 0) {
          // TODO(hjd): Look at the next few bytes for real size.
          PERFETTO_CHECK(false);
        }
        const uint8_t* next = ptr + 4 * event_header.type_or_length;

        uint16_t ftrace_event_id;
        if (!ReadAndAdvance<uint16_t>(&ptr, end, &ftrace_event_id))
          return false;
        if (!filter->IsEventEnabled(ftrace_event_id)) {
          ptr = next;
          break;
        }

        // Common headers:
        // TODO(hjd): Read this format dynamically?
        uint8_t flags;
        uint8_t preempt_count;
        uint32_t pid;
        if (!ReadAndAdvance<uint8_t>(&ptr, end, &flags))
          return false;
        if (!ReadAndAdvance<uint8_t>(&ptr, end, &preempt_count))
          return false;
        if (!ReadAndAdvance<uint32_t>(&ptr, end, &pid))
          return false;

        // PERFETTO_DLOG("Event type=%d pid=%d", ftrace_event_id, pid);

        protos::pbzero::FtraceEvent* event = bundle->add_event();
        event->set_pid(pid);

        // TODO(hjd): Replace this handrolled code with generic parsing code.
        if (ftrace_event_id == print_id) {
          protos::pbzero::PrintFtraceEvent* print_event = event->set_print();
          // Trace Marker Parser
          uint64_t ip;
          if (!ReadAndAdvance<uint64_t>(&ptr, end, &ip))
            return false;
          print_event->set_ip(ip);

          // TODO(hjd): Not sure if this is null-terminated.
          const uint8_t* buf_start = ptr;
          const uint8_t* buf_end = next - 2;
          print_event->set_buf(reinterpret_cast<const char*>(buf_start),
                               buf_end - buf_start);
          print_event->Finalize();
        }

        // TODO(hjd): Replace this handrolled code with generic parsing code.
        if (ftrace_event_id == sched_switch_id) {
          protos::pbzero::SchedSwitchFtraceEvent* switch_event =
              event->set_sched_switch();

          char prev_comm[16];
          uint32_t prev_pid;
          uint32_t prev_prio;
          uint64_t prev_state;
          char next_comm[16];
          uint32_t next_pid;
          uint32_t next_prio;

          // TODO(hjd): Avoid this copy.
          if (!ReadAndAdvance<char[16]>(&ptr, end, &prev_comm))
            return false;
          if (!ReadAndAdvance<uint32_t>(&ptr, end, &prev_pid))
            return false;
          if (!ReadAndAdvance<uint32_t>(&ptr, end, &prev_prio))
            return false;
          if (!ReadAndAdvance<uint64_t>(&ptr, end, &prev_state))
            return false;
          if (!ReadAndAdvance<char[16]>(&ptr, end, &next_comm))
            return false;
          if (!ReadAndAdvance<uint32_t>(&ptr, end, &next_pid))
            return false;
          if (!ReadAndAdvance<uint32_t>(&ptr, end, &next_prio))
            return false;
          // TODO(hjd): Not sure if this is null-terminated.
          prev_comm[15] = '\0';
          switch_event->set_prev_comm(prev_comm);
          switch_event->set_prev_pid(prev_pid);
          switch_event->set_prev_prio(prev_prio);
          switch_event->set_prev_state(prev_state);
          // TODO(hjd): Not sure if this is null-terminated.
          next_comm[15] = '\0';
          switch_event->set_next_comm(next_comm);
          switch_event->set_next_pid(next_pid);
          switch_event->set_next_prio(next_prio);
          switch_event->Finalize();
        }

        event->Finalize();

        // Jump to next event.
        ptr = next;
      }
    }
  }
  return true;
}

}  // namespace perfetto
