/*
 * 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 "ftrace_procfs.h"
#include "gtest/gtest.h"
#include "proto_translation_table.h"

#include "protozero/scattered_stream_writer.h"
#include "scattered_stream_delegate_for_testing.h"

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

namespace perfetto {

namespace {

const size_t kPageSize = 4096;

std::unique_ptr<uint8_t[]> MakeBuffer(size_t size) {
  return std::unique_ptr<uint8_t[]>(new uint8_t[size]);
}

class BinaryWriter {
 public:
  BinaryWriter(uint8_t* ptr, size_t size) : ptr_(ptr), size_(size) {}

  template <typename T>
  void Write(T t) {
    memcpy(ptr_, &t, sizeof(T));
    ptr_ += sizeof(T);
    PERFETTO_CHECK(ptr_ < ptr_ + size_);
  }

  void WriteEventHeader(uint32_t time_delta, uint32_t entry_type) {
    // Entry header is a packed time delta (d) and type (t):
    // dddddddd dddddddd dddddddd dddttttt
    Write<uint32_t>((time_delta << 5) | (entry_type & 0x1f));
  }

  void WriteString(const char* s) {
    char c;
    while ((c = *s++)) {
      Write<char>(c);
    }
  }

 private:
  uint8_t* ptr_;
  size_t size_;
};

}  // namespace

TEST(EventFilterTest, EventFilter) {
  using Event = ProtoTranslationTable::Event;
  using Field = ProtoTranslationTable::Field;

  std::vector<Field> common_fields;
  std::vector<Event> events;

  {
    Event event;
    event.name = "foo";
    event.ftrace_event_id = 1;
    events.push_back(event);
  }

  {
    Event event;
    event.name = "bar";
    event.ftrace_event_id = 10;
    events.push_back(event);
  }

  ProtoTranslationTable table(events, std::move(common_fields));
  EventFilter filter(table, std::set<std::string>({"foo"}));

  EXPECT_TRUE(filter.IsEventEnabled(1));
  EXPECT_FALSE(filter.IsEventEnabled(2));
  EXPECT_FALSE(filter.IsEventEnabled(10));
}

TEST(CpuReaderTest, ReadAndAdvanceNumber) {
  uint64_t expected = 42;
  uint64_t actual = 0;
  uint8_t buffer[8] = {};
  const uint8_t* start = buffer;
  const uint8_t* ptr = buffer;
  memcpy(&buffer, &expected, 8);
  EXPECT_TRUE(CpuReader::ReadAndAdvance<uint64_t>(&ptr, ptr + 8, &actual));
  EXPECT_EQ(ptr, start + 8);
  EXPECT_EQ(actual, expected);
}

TEST(CpuReaderTest, ReadAndAdvancePlainStruct) {
  struct PlainStruct {
    uint64_t timestamp;
    uint64_t length;
  };

  uint64_t expected[2] = {42, 999};
  PlainStruct actual;
  uint8_t buffer[16] = {};
  const uint8_t* start = buffer;
  const uint8_t* ptr = buffer;
  memcpy(&buffer, &expected, 16);
  EXPECT_TRUE(CpuReader::ReadAndAdvance<PlainStruct>(&ptr, ptr + 16, &actual));
  EXPECT_EQ(ptr, start + 16);
  EXPECT_EQ(actual.timestamp, 42ul);
  EXPECT_EQ(actual.length, 999ul);
}

TEST(CpuReaderTest, ReadAndAdvanceComplexStruct) {
  struct ComplexStruct {
    uint64_t timestamp;
    uint32_t length;
    uint32_t : 24;
    uint32_t overwrite : 8;
  };

  uint64_t expected[2] = {42, 0xcdffffffabababab};
  ComplexStruct actual = {};
  uint8_t buffer[16] = {};
  const uint8_t* start = buffer;
  const uint8_t* ptr = buffer;
  memcpy(&buffer, &expected, 16);
  EXPECT_TRUE(
      CpuReader::ReadAndAdvance<ComplexStruct>(&ptr, ptr + 16, &actual));
  EXPECT_EQ(ptr, start + 16);
  EXPECT_EQ(actual.timestamp, 42ul);
  EXPECT_EQ(actual.length, 0xabababab);
  EXPECT_EQ(actual.overwrite, 0xCDu);
}

TEST(CpuReaderTest, ReadAndAdvanceOverruns) {
  uint64_t result = 42;
  uint8_t buffer[7] = {};
  const uint8_t* start = buffer;
  const uint8_t* ptr = buffer;
  EXPECT_FALSE(CpuReader::ReadAndAdvance<uint64_t>(&ptr, ptr + 7, &result));
  EXPECT_EQ(ptr, start);
  EXPECT_EQ(result, 42ul);
}

TEST(CpuReaderTest, ReadAndAdvanceAtEnd) {
  uint8_t result = 42;
  uint8_t buffer[8] = {};
  const uint8_t* start = buffer;
  const uint8_t* ptr = buffer;
  EXPECT_FALSE(CpuReader::ReadAndAdvance<uint8_t>(&ptr, ptr, &result));
  EXPECT_EQ(ptr, start);
  EXPECT_EQ(result, 42);
}

TEST(CpuReaderTest, ReadAndAdvanceUnderruns) {
  uint64_t expected = 42;
  uint64_t actual = 0;
  uint8_t buffer[9] = {};
  const uint8_t* start = buffer;
  const uint8_t* ptr = buffer;
  memcpy(&buffer, &expected, 8);
  EXPECT_TRUE(CpuReader::ReadAndAdvance<uint64_t>(&ptr, ptr + 8, &actual));
  EXPECT_EQ(ptr, start + 8);
  EXPECT_EQ(actual, expected);
}

TEST(CpuReaderTest, ParseEmpty) {
  std::string path = "ftrace_reader/test/data/android_seed_N2F62_3.10.49/";
  FtraceProcfs ftrace_procfs(path);
  auto table = ProtoTranslationTable::Create(&ftrace_procfs);
  CpuReader(table.get(), 42, base::ScopedFile());
}

TEST(CpuReaderTest, ParseSimpleEvent) {
  std::string path = "ftrace_reader/test/data/android_seed_N2F62_3.10.49/";
  FtraceProcfs ftrace(path);
  auto table = ProtoTranslationTable::Create(&ftrace);

  std::unique_ptr<uint8_t[]> in_page = MakeBuffer(kPageSize);
  std::unique_ptr<uint8_t[]> out_page = MakeBuffer(kPageSize);

  BinaryWriter writer(in_page.get(), kPageSize);
  // Timestamp:
  writer.Write<uint64_t>(999);
  // Page length:
  writer.Write<uint64_t>(35);
  // 4 Header:
  writer.WriteEventHeader(1 /* time delta */, 8 /* entry type */);
  // 6 Event type:
  writer.Write<uint16_t>(5);
  // 7 Flags:
  writer.Write<uint8_t>(0);
  // 8 Preempt count:
  writer.Write<uint8_t>(0);
  // 12 PID:
  writer.Write<uint32_t>(72);
  // 20 Instruction pointer:
  writer.Write<uint64_t>(0);
  // 35 String:
  writer.WriteString("Hello, world!\n");

  EventFilter filter(*table, std::set<std::string>({"print"}));

  perfetto::ScatteredStreamDelegateForTesting delegate(kPageSize);
  protozero::ScatteredStreamWriter stream_writer(&delegate);
  delegate.set_writer(&stream_writer);
  protos::pbzero::FtraceEventBundle message;
  message.Reset(&stream_writer);

  CpuReader::ParsePage(42 /* cpu number */, in_page.get(), kPageSize, &filter,
                       &message, table.get());

  size_t msg_size =
      delegate.chunks().size() * kPageSize - stream_writer.bytes_available();
  std::unique_ptr<uint8_t[]> proto = delegate.StitchChunks(msg_size);

  protos::FtraceEventBundle proto_bundle;
  proto_bundle.ParseFromArray(proto.get(), static_cast<int>(msg_size));

  EXPECT_EQ(proto_bundle.cpu(), 42u);
  ASSERT_EQ(proto_bundle.event().size(), 1);
  const protos::FtraceEvent& proto_event = proto_bundle.event().Get(0);
  EXPECT_EQ(proto_event.pid(), 72u);
  EXPECT_TRUE(proto_event.has_print());
  // TODO(hjd): Check if this is the correct format.
  EXPECT_EQ(proto_event.print().buf(), "Hello, world!\n");
}

}  // namespace perfetto
