// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_LIB_ZXDUMP_TEST_DATA_HOLDER_H_
#define SRC_LIB_ZXDUMP_TEST_DATA_HOLDER_H_

#include <lib/zxdump/task.h>
#include <zircon/syscalls/object.h>

#include <string>
#include <string_view>
#include <tuple>
#include <type_traits>

#include <gtest/gtest.h>

namespace zxdump::testing {

// TestDataHolder<T...> holds data from get_info and get_property calls.
// Each T is InfoTraits<...> or PropertyTraits<...>.  Get<T>() yields a
// TestDataItem<T>, defined below.  Data can be easily checked against
// another identically-typed data holder, or individual items can be
// checked against other like items.

template <class Traits>
class TestDataItem;

template <class... ItemTraits>
class TestDataHolder {
 public:
  // Get the TestDataItem for the given InfoTraits<...> or PropertyTraits<...>.
  template <class Item>
  decltype(auto) Get() {
    return std::get<TestDataItem<Item>>(items_);
  }

  template <class Item>
  decltype(auto) Get() const {
    return std::get<TestDataItem<Item>>(items_);
  }

  template <class Item>
  void Check(const TestDataItem<Item>& other) const {
    Get<Item>().Check(other);
  }

  // Check each item.
  void Check(const TestDataHolder& other) const { (Check(other.Get<ItemTraits>()), ...); }

  // This fills each item using get_info / get_property.
  void Fill(zxdump::Object& object) { (Get<ItemTraits>().Fill(object), ...); }

 private:
  std::tuple<TestDataItem<ItemTraits>...> items_;
};

// This gets instantiated with the InfoTraits<...> or PropertyTraits<...>
// type so it can be specialized on those.  The partial specializations below
// just instantiate this again with the Traits::type.  This default
// instantiation works for simple types where EXPECT_EQ works.  It also works
// when the constexpr variable kTestDataValueStruct<T> is specialized to
// return a tuple of T::* member pointers.
template <typename T>
struct TestDataValueType {
  using type = T;

  static constexpr bool kIsVector = false;

  static void Check(std::string_view name, const type& old_value, const type& new_value) {
    EXPECT_EQ(old_value, new_value) << name;
  }
};

// When Traits::type is a span, this default specialization just checks for
// matching elements by instantiating again on the element type.
template <typename T>
struct TestDataValueType<cpp20::span<const T>> {
  using type = std::vector<T>;

  static constexpr bool kIsVector = true;

  static void Check(std::string_view name, cpp20::span<const T> old_value,
                    cpp20::span<const T> new_value) {
    ASSERT_EQ(old_value.size(), new_value.size()) << name;
    for (size_t i = 0; i < old_value.size(); ++i) {
      TestDataValueType<T>::Check(std::string(name) + "[" + std::to_string(i) + "]", old_value[i],
                                  new_value[i]);
    }
  }
};

// If not specialized on a specific InfoTraits<...>, instantiate for the data
// type.
template <uint32_t Topic>
struct TestDataValueType<InfoTraits<Topic>>
    : public TestDataValueType<typename InfoTraits<Topic>::type> {};

// If not specialized on a specific PropertyTraits<...>, instantiate for the
// data type.
template <uint32_t Property>
struct TestDataValueType<PropertyTraits<Property>>
    : public TestDataValueType<typename PropertyTraits<Property>::type> {};

// TestDataItem looks a little like a smart pointer to Traits::type.  When
// Traits::type is a span<T>, it acts like a smart pointer to std::vector<T>.
template <class Traits>
class TestDataItem {
 public:
  const auto& operator*() const { return value_; }

  const auto* operator->() const { return &value_; }

  // This fills the item with an explicit value, which might be a span.
  void Fill(const typename Traits::type& value) {
    if constexpr (TestDataValueType<Traits>::kIsVector) {
      value_ = typename TestDataValueType<Traits>::type(value.begin(), value.end());
    } else {
      value_ = value;
    }
  }

  // This fills the item using get_info / get_property.
  void Fill(zxdump::Object& object) {
    auto result = GetData{}(object);
    ASSERT_TRUE(result.is_ok()) << result.error_value();
    Fill(result.value());
  }

  // Check a new value against this value.  For thread and process items this
  // is usually just doing EXPECT_EQ, expecting both samples to be taken
  // while the process is suspended and so nothing changes.  For job and
  // kernel values that keep changing, it checks for the new value being
  // plausible for a sample taken later, e.g. EXPECT_GE for statistics.
  void Check(const TestDataItem& new_item) const { Check(*new_item); }

  // Check a new raw value rather than another identical TestDataItem.
  // This has specializations for all the traits types.
  void Check(const typename Traits::type& new_value) const {
    ItemValueType::Check(Traits::kName, value_, new_value);
  }

 private:
  using ItemValueType = TestDataValueType<Traits>;

  // This is a separate template on Traits so it can be specialized.
  template <class T = Traits>
  struct GetData;

  template <uint32_t Topic>
  struct GetData<InfoTraits<Topic>> {
    auto operator()(zxdump::Object& object) const { return object.get_info<Topic>(); }
  };

  template <uint32_t Property>
  struct GetData<PropertyTraits<Property>> {
    auto operator()(zxdump::Object& object) const { return object.get_property<Property>(); }
  };

  typename TestDataValueType<Traits>::type value_;
};

template <>
struct TestDataValueType<zx_info_cpu_stats_t> {
  using type = zx_info_cpu_stats_t;

  static constexpr bool kIsVector = false;

  static void Check(std::string_view name, const type& old_value, const type& new_value);
};

template <>
struct TestDataValueType<zx_info_kmem_stats_t> {
  using type = zx_info_kmem_stats_t;

  static constexpr bool kIsVector = false;

  static void Check(std::string_view name, const type& old_value, const type& new_value);
};

template <>
struct TestDataValueType<zx_arm64_info_guest_stats_t> {
  using type = zx_arm64_info_guest_stats_t;

  static constexpr bool kIsVector = false;

  static void Check(std::string_view name, const type& old_value, const type& new_value);
};

template <>
struct TestDataValueType<zx_riscv64_info_guest_stats_t> {
  using type = zx_riscv64_info_guest_stats_t;

  static constexpr bool kIsVector = false;

  static void Check(std::string_view name, const type& old_value, const type& new_value);
};

template <>
struct TestDataValueType<zx_x86_64_info_guest_stats_t> {
  using type = zx_x86_64_info_guest_stats_t;

  static constexpr bool kIsVector = false;

  static void Check(std::string_view name, const type& old_value, const type& new_value);
};

}  // namespace zxdump::testing

#endif  // SRC_LIB_ZXDUMP_TEST_DATA_HOLDER_H_
