// Copyright (c) 2014 The Chromium OS 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 "chromiumos-wide-profiling/test_perf_data.h"

#include <stddef.h>

#include <algorithm>
#include <ostream>  // NOLINT
#include <vector>

#include "base/logging.h"

#include "chromiumos-wide-profiling/compat/string.h"
#include "chromiumos-wide-profiling/kernel/perf_internals.h"
#include "chromiumos-wide-profiling/utils.h"

namespace quipper {
namespace testing {

namespace {

// Write extra bytes to an output stream.
void WriteExtraBytes(size_t size, std::ostream* out) {
  std::vector<char> padding(size);
  out->write(padding.data(), size);
}

// TODO(sque): These following two functions are copied from elsewhere. Put them
// in a common location and add a unit test.
u8 ReverseByte(u8 x) {
  x = (x & 0xf0) >> 4 | (x & 0x0f) << 4;  // exchange nibbles
  x = (x & 0xcc) >> 2 | (x & 0x33) << 2;  // exchange pairs
  x = (x & 0xaa) >> 1 | (x & 0x55) << 1;  // exchange neighbors
  return x;
}

void SwapBitfieldOfBits(u8* field, size_t len) {
  for (size_t i = 0; i < len; i++) {
    field[i] = ReverseByte(field[i]);
  }
}

}  // namespace

ExamplePerfDataFileHeader::ExamplePerfDataFileHeader(
    const size_t attr_count,
    const u64 data_size,
    const unsigned long features) {  // NOLINT
  CHECK_EQ(112U, sizeof(perf_file_attr)) << "perf_file_attr has changed size!";
  const size_t attrs_size = attr_count * sizeof(struct perf_file_attr);
  header_ = {
    .magic = kPerfMagic,
    .size = 104,
    .attr_size = sizeof(perf_file_attr),
    .attrs = {.offset = 104, .size = attrs_size},
    .data = {.offset = 104 + attrs_size, .size = data_size},
    .event_types = {0},
    .adds_features = {features, 0, 0, 0},
  };
}

void ExamplePerfDataFileHeader::WriteTo(std::ostream* out) const {
  struct perf_file_header local_header = {
    .magic = MaybeSwap64(header_.magic),
    .size = MaybeSwap64(header_.size),
    .attr_size = MaybeSwap64(header_.attr_size),
    .attrs = { .offset = MaybeSwap64(header_.attrs.offset),
               .size = MaybeSwap64(header_.attrs.size) },
    .data = { .offset = MaybeSwap64(header_.data.offset),
               .size = MaybeSwap64(header_.data.size) },
    .event_types = { .offset = MaybeSwap64(header_.event_types.offset),
               .size = MaybeSwap64(header_.event_types.size) },
    .adds_features = {0},
  };
  // Copy over the features bits manually since the byte swapping is more
  // complicated.
  for (size_t i = 0;
       i < sizeof(header_.adds_features) / sizeof(uint64_t);
       ++i) {
    reinterpret_cast<uint64_t*>(local_header.adds_features)[i] =
      MaybeSwap64(reinterpret_cast<const uint64_t*>(header_.adds_features)[i]);
  }

  out->write(reinterpret_cast<const char*>(&local_header),
             sizeof(local_header));
  // Use original header values that weren't endian-swapped.
  CHECK_EQ(static_cast<u64>(out->tellp()), header_.size);
  CHECK_EQ(static_cast<u64>(out->tellp()), header_.attrs.offset);
}

ExamplePerfDataFileHeader_CustomAttrSize::
    ExamplePerfDataFileHeader_CustomAttrSize(
        const size_t event_attr_size, const u64 data_size)
            : ExamplePerfDataFileHeader(1, data_size, 0) {  // NOLINT
  const size_t file_attr_size = event_attr_size + sizeof(perf_file_section);
  header_ = {
    .magic = kPerfMagic,
    .size = 104,
    .attr_size = file_attr_size,
    .attrs = {.offset = 104, .size = file_attr_size},
    .data = {.offset = 104 + file_attr_size, .size = data_size},
    .event_types = {0},
    .adds_features = {0, 0, 0, 0},
  };
}

void ExamplePipedPerfDataFileHeader::WriteTo(std::ostream* out) const {
  const perf_pipe_file_header header = {
    .magic = kPerfMagic,
    .size = 16,
  };
  out->write(reinterpret_cast<const char*>(&header), sizeof(header));
  CHECK_EQ(static_cast<u64>(out->tellp()), header.size);
}

void ExamplePerfEventAttrEvent_Hardware::WriteTo(std::ostream* out) const {
  // Due to the unnamed union fields (eg, sample_period), this structure can't
  // be initialized with designated initializers.
  perf_event_attr attr = {};
  attr.type = PERF_TYPE_HARDWARE;
  attr.size = attr_size_;
  attr.config = config_;
  attr.sample_period = 100001;
  attr.sample_type = sample_type_;
  attr.sample_id_all = sample_id_all_;

  const attr_event event = {
    .header = {
      .type = PERF_RECORD_HEADER_ATTR,
      .misc = 0,
      // No ids to add to size.
      .size = static_cast<u16>(sizeof(event.header) + attr.size),
    },
    .attr = attr,
  };

  out->write(reinterpret_cast<const char*>(&event),
             std::min(sizeof(event), static_cast<size_t>(event.header.size)));
  if (sizeof(event) < event.header.size)
    WriteExtraBytes(event.header.size - sizeof(event), out);
}

void ExamplePerfFileAttr_Hardware::WriteTo(std::ostream* out) const {
  // Due to the unnamed union fields (eg, sample_period), this structure can't
  // be initialized with designated initializers.
  perf_event_attr attr = {0};
  attr.type = MaybeSwap32(PERF_TYPE_HARDWARE);
  attr.size = MaybeSwap32(attr_size_);
  attr.config = MaybeSwap64(config_);
  attr.sample_period = MaybeSwap64(1);
  attr.sample_type = MaybeSwap64(sample_type_);
  // Bit fields.
  attr.sample_id_all = sample_id_all_;
  attr.precise_ip = 2;    // For testing a bit field that is more than one bit.

  if (is_cross_endian()) {
    // The order of operations here is for native-to-cross-endian conversion.
    // Contrast with similar code in PerfReader for cross-endian-to-native
    // conversion, which performs these swap operations in reverse order.
    const auto tmp = attr.precise_ip;
    attr.precise_ip = (tmp & 0x2) >> 1 | (tmp & 0x1) << 1;

    auto *const bitfield_start = &attr.read_format + 1;
    SwapBitfieldOfBits(reinterpret_cast<u8*>(bitfield_start), sizeof(u64));
  }

  // perf_event_attr can be of a size other than the static struct size. Thus we
  // cannot simply statically create a perf_file_attr (which contains a
  // perf_event_attr and a perf_file_section). Instead, create and write each
  // component separately.
  out->write(reinterpret_cast<const char*>(&attr),
             std::min(sizeof(attr), static_cast<size_t>(attr_size_)));
  if (sizeof(attr) < attr_size_)
    WriteExtraBytes(attr_size_ - sizeof(attr), out);

  const perf_file_section ids = { .offset = MaybeSwap64(104),
                                  .size = MaybeSwap64(0) };
  out->write(reinterpret_cast<const char*>(&ids), sizeof(ids));
}

void ExamplePerfFileAttr_Tracepoint::WriteTo(std::ostream* out) const {
  // Due to the unnamed union fields (eg, sample_period), this structure can't
  // be initialized with designated initializers.
  perf_event_attr attr = {};
  // See kernel src: tools/perf/util/evsel.c perf_evsel__newtp()
  attr.type = PERF_TYPE_TRACEPOINT;
  attr.size = sizeof(perf_event_attr);
  attr.config = tracepoint_event_id_;
  attr.sample_period = 1;
  attr.sample_type = (PERF_SAMPLE_IP |
                      PERF_SAMPLE_TID |
                      PERF_SAMPLE_TIME |
                      PERF_SAMPLE_CPU |
                      PERF_SAMPLE_PERIOD |
                      PERF_SAMPLE_RAW);

  const perf_file_attr file_attr = {
    .attr = attr,
    .ids = {.offset = 104, .size = 0},
  };
  out->write(reinterpret_cast<const char*>(&file_attr), sizeof(file_attr));
}

void ExampleMmapEvent::WriteTo(std::ostream* out) const {
  const size_t filename_aligned_length =
      GetUint64AlignedStringLength(filename_);
  const size_t event_size =
      offsetof(struct mmap_event, filename) +
      filename_aligned_length +
      sample_id_.size();  // sample_id_all

  struct mmap_event event = {
    .header = {
      .type = MaybeSwap32(PERF_RECORD_MMAP),
      .misc = 0,
      .size = MaybeSwap16(static_cast<u16>(event_size)),
    },
    .pid = MaybeSwap32(pid_),
    .tid = MaybeSwap32(pid_),
    .start = MaybeSwap64(start_),
    .len = MaybeSwap64(len_),
    .pgoff = MaybeSwap64(pgoff_),
    // .filename = ..., // written separately
  };

  const size_t pre_mmap_offset = out->tellp();
  out->write(reinterpret_cast<const char*>(&event),
             offsetof(struct mmap_event, filename));
  *out << filename_
       << string(filename_aligned_length - filename_.size(), '\0');
  out->write(sample_id_.data(), sample_id_.size());
  const size_t written_event_size =
      static_cast<size_t>(out->tellp()) - pre_mmap_offset;
  CHECK_EQ(event_size,
           static_cast<u64>(written_event_size));
}

void ExampleMmap2Event::WriteTo(std::ostream* out) const {
  const size_t filename_aligned_length =
      GetUint64AlignedStringLength(filename_);
  const size_t event_size =
      offsetof(struct mmap2_event, filename) +
      filename_aligned_length +
      sample_id_.size();  // sample_id_all

  struct mmap2_event event = {
    .header = {
      .type = PERF_RECORD_MMAP2,
      .misc = 0,
      .size = static_cast<u16>(event_size),
    },
    .pid = pid_, .tid = pid_,
    .start = start_,
    .len = len_,
    .pgoff = pgoff_,
    .maj = 6,
    .min = 7,
    .ino = 8,
    .ino_generation = 9,
    .prot = 1|2,  // == PROT_READ | PROT_WRITE
    .flags = 2,   // == MAP_PRIVATE
    // .filename = ..., // written separately
  };

  const size_t pre_mmap_offset = out->tellp();
  out->write(reinterpret_cast<const char*>(&event),
             offsetof(struct mmap2_event, filename));
  *out << filename_
       << string(filename_aligned_length - filename_.size(), '\0');
  out->write(sample_id_.data(), sample_id_.size());
  const size_t written_event_size =
      static_cast<size_t>(out->tellp()) - pre_mmap_offset;
  CHECK_EQ(event.header.size,
           static_cast<u64>(written_event_size));
}

void ExampleForkExitEvent::WriteTo(std::ostream* out) const {
  const size_t event_size = sizeof(struct fork_event) + sample_id_.size();

  struct fork_event event = {
    .header = {
      .type = MaybeSwap32(type_),
      .misc = 0,
      .size = MaybeSwap16(static_cast<u16>(event_size)),
    },
    .pid = MaybeSwap32(pid_), .ppid = MaybeSwap32(ppid_),
    .tid = MaybeSwap32(tid_), .ptid = MaybeSwap32(ptid_),
    .time = MaybeSwap64(time_),
  };

  const size_t pre_event_offset = out->tellp();
  out->write(reinterpret_cast<const char*>(&event), sizeof(event));
  out->write(sample_id_.data(), sample_id_.size());
  const size_t written_event_size =
      static_cast<size_t>(out->tellp()) - pre_event_offset;
  CHECK_EQ(MaybeSwap16(event.header.size),
           static_cast<u64>(written_event_size));
}

void FinishedRoundEvent::WriteTo(std::ostream* out) const {
  const perf_event_header event = {
    .type = PERF_RECORD_FINISHED_ROUND,
    .misc = 0,
    .size = sizeof(struct perf_event_header),
  };
  out->write(reinterpret_cast<const char*>(&event), sizeof(event));
}

size_t ExamplePerfSampleEvent::GetSize() const {
  return sizeof(struct sample_event) + sample_info_.size();
}

void ExamplePerfSampleEvent::WriteTo(std::ostream* out) const {
  const sample_event event = {
    .header = {
      .type = MaybeSwap32(PERF_RECORD_SAMPLE),
      .misc = MaybeSwap16(PERF_RECORD_MISC_USER),
      .size = MaybeSwap16(static_cast<u16>(GetSize())),
    }
  };
  out->write(reinterpret_cast<const char*>(&event), sizeof(event));
  out->write(sample_info_.data(), sample_info_.size());
}

ExamplePerfSampleEvent_BranchStack::ExamplePerfSampleEvent_BranchStack()
  : ExamplePerfSampleEvent(
      SampleInfo()
      .BranchStack_nr(16)
      .BranchStack_lbr(0x00007f4a313bb8cc, 0x00007f4a313bdb40, 0x02)
      .BranchStack_lbr(0x00007f4a30ce4de2, 0x00007f4a313bb8b3, 0x02)
      .BranchStack_lbr(0x00007f4a313bb8b0, 0x00007f4a30ce4de0, 0x01)
      .BranchStack_lbr(0x00007f4a30ff45c1, 0x00007f4a313bb8a0, 0x02)
      .BranchStack_lbr(0x00007f4a30ff49f2, 0x00007f4a30ff45bb, 0x02)
      .BranchStack_lbr(0x00007f4a30ff4a98, 0x00007f4a30ff49ed, 0x02)
      .BranchStack_lbr(0x00007f4a30ff4a7c, 0x00007f4a30ff4a91, 0x02)
      .BranchStack_lbr(0x00007f4a30ff4a34, 0x00007f4a30ff4a46, 0x02)
      .BranchStack_lbr(0x00007f4a30ff4c22, 0x00007f4a30ff4a0e, 0x02)
      .BranchStack_lbr(0x00007f4a30ff4bb3, 0x00007f4a30ff4c1b, 0x01)
      .BranchStack_lbr(0x00007f4a30ff4a09, 0x00007f4a30ff4b60, 0x02)
      .BranchStack_lbr(0x00007f4a30ff49e8, 0x00007f4a30ff4a00, 0x02)
      .BranchStack_lbr(0x00007f4a30ff42db, 0x00007f4a30ff49e0, 0x02)
      .BranchStack_lbr(0x00007f4a30ff42bb, 0x00007f4a30ff42d4, 0x02)
      .BranchStack_lbr(0x00007f4a333bf88b, 0x00007f4a30ff42ac, 0x02)
      .BranchStack_lbr(0x00007f4a333bf853, 0x00007f4a333bf885, 0x02)) {
}

// Event size matching the event produced above
const size_t ExamplePerfSampleEvent_BranchStack::kEventSize =
    (1 /*perf_event_header*/ + 1 /*nr*/ + 16*3 /*lbr*/) * sizeof(u64);

void ExamplePerfSampleEvent_Tracepoint::WriteTo(std::ostream* out) const {
  const sample_event event = {
    .header = {
      .type = PERF_RECORD_SAMPLE,
      .misc = PERF_RECORD_MISC_USER,
      .size = 0x0078,
    }
  };
  const u64 sample_event_array[] = {
    0x00007f999c38d15a,  // IP
    0x0000068d0000068d,  // TID (u32 pid, tid)
    0x0001e0211cbab7b9,  // TIME
    0x0000000000000000,  // CPU
    0x0000000000000001,  // PERIOD
    0x0000004900000044,  // RAW (u32 size = 0x44 = 68 = 4 + 8*sizeof(u64))
    0x000000090000068d,  //  .
    0x0000000000000000,  //  .
    0x0000100000000000,  //  .
    0x0000000300000000,  //  .
    0x0000002200000000,  //  .
    0xffffffff00000000,  //  .
    0x0000000000000000,  //  .
    0x0000000000000000,  //  .
  };
  CHECK_EQ(event.header.size,
           sizeof(event.header) + sizeof(sample_event_array));
  out->write(reinterpret_cast<const char*>(&event), sizeof(event));
  out->write(reinterpret_cast<const char*>(sample_event_array),
             sizeof(sample_event_array));
}

// Event size matching the event produced above
const size_t ExamplePerfSampleEvent_Tracepoint::kEventSize =
    (1 /*perf_event_header*/ + 14 /*sample array*/) * sizeof(u64);

void ExampleStringMetadata::WriteTo(std::ostream* out) const {
  const perf_file_section &index_entry = index_entry_.index_entry_;
  CHECK_EQ(static_cast<u64>(out->tellp()), index_entry.offset);
  const u32 data_size_value = MaybeSwap32(data_.size());
  out->write(reinterpret_cast<const char*>(&data_size_value),
             sizeof(data_size_value));
  out->write(data_.data(), data_.size());

  CHECK_EQ(static_cast<u64>(out->tellp()), index_entry.offset + size());
}

void ExampleStringMetadataEvent::WriteTo(std::ostream* out) const {
  const size_t initial_position = out->tellp();

  const u32 data_size = data_.size();
  const perf_event_header header = {
    .type = type_,
    .misc = 0,
    .size = static_cast<u16>(sizeof(header) + sizeof(data_size) + data_.size()),
  };
  out->write(reinterpret_cast<const char*>(&header), sizeof(header));

  out->write(reinterpret_cast<const char*>(&data_size), sizeof(data_size));
  out->write(reinterpret_cast<const char*>(data_.data()), data_.size());

  CHECK_EQ(static_cast<u64>(out->tellp()), initial_position + header.size);
}

static const char kTraceMetadataValue[] =
    "\x17\x08\x44tracing0.5BLAHBLAHBLAH....";

const std::vector<char> ExampleTracingMetadata::Data::kTraceMetadata(
    kTraceMetadataValue, kTraceMetadataValue+sizeof(kTraceMetadataValue)-1);

void ExampleTracingMetadata::Data::WriteTo(std::ostream* out) const {
  const perf_file_section &index_entry = parent_->index_entry_.index_entry_;
  CHECK_EQ(static_cast<u64>(out->tellp()), index_entry.offset);
  out->write(kTraceMetadata.data(), kTraceMetadata.size());
  CHECK_EQ(static_cast<u64>(out->tellp()),
           index_entry.offset + index_entry.size);
}

}  // namespace testing
}  // namespace quipper
