// 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 <algorithm>
#include <ostream>  // NOLINT
#include <vector>

#include "base/logging.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
