// 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);
}

}  // 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(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 {
  out->write(reinterpret_cast<const char*>(&header_), sizeof(header_));
  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 = {};
  attr.type = PERF_TYPE_HARDWARE;
  attr.size = attr_size_;
  attr.config = config_;
  attr.sample_period = 1;
  attr.sample_type = sample_type_;
  attr.sample_id_all = sample_id_all_;

  // 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 = 104, .size = 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 = PERF_RECORD_MMAP,
      .misc = 0,
      .size = static_cast<u16>(event_size),
    },
    .pid = pid_, .tid = pid_,
    .start = start_,
    .len = len_,
    .pgoff = 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.header.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 = type_,
      .misc = 0,
      .size = static_cast<u16>(event_size),
    },
    .pid = pid_, .ppid = ppid_,
    .tid = tid_, .ptid = ptid_,
    .time = 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(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 = PERF_RECORD_SAMPLE,
      .misc = PERF_RECORD_MISC_USER,
      .size = 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 = data_.size();
  out->write(reinterpret_cast<const char*>(&data_size), sizeof(data_size));
  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
