// Copyright 2021 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.

#ifndef DIAGNOSTICS_COMMON_MOJO_TYPE_UTILS_H_
#define DIAGNOSTICS_COMMON_MOJO_TYPE_UTILS_H_

#include <algorithm>
#include <string>
#include <type_traits>
#include <vector>

#include <mojo/public/cpp/bindings/struct_ptr.h>

#include "mojo/cros_healthd_probe.mojom.h"

namespace chromeos {
namespace cros_healthd {
namespace mojom {
// Union types don't have default operator<. Define them so we can use std::sort
// to sort them.
bool operator<(const BusInfo& a, const BusInfo& b);
}  // namespace mojom
}  // namespace cros_healthd
}  // namespace chromeos

namespace diagnostics {
namespace internal {
constexpr auto kEqualStr = "[Equal]";
constexpr auto kNullStr = "[Null]";
constexpr auto kNotNullStr = "[Not Null]";

std::string Indent(const std::string& s);

std::string StringCompareFormat(const std::string& a, const std::string& b);
}  // namespace internal

// Type traits templates for identifying the mojo StructPtr types.
template <typename>
class IsStructPtr : public std::false_type {};
template <typename T>
class IsStructPtr<::mojo::StructPtr<T>> : public std::true_type {};
template <typename T>
class IsStructPtr<::mojo::InlinedStructPtr<T>> : public std::true_type {};

// Type traits templates for identifying the mojo Union types.
template <typename T>
class HasWhichFunction {
  template <typename U>
  static int8_t test_funtion(decltype(&U::which));
  template <typename U>
  static int16_t test_funtion(...);

 public:
  static constexpr bool value = (sizeof(test_funtion<T>(0)) == sizeof(int8_t));
};
template <typename T>
class IsMojoUnion : public HasWhichFunction<T> {};

// Type traits templates for identifying the vector.
template <typename>
class IsVector : public std::false_type {};
template <typename T>
class IsVector<std::vector<T>> : public std::true_type {};

// Helper type for better compiler error message.
template <typename T>
class UndefinedMojoType : public std::false_type {};

// Returns the difference between |a| and |b|. This is for the debugging of the
// unittest related to mojo types. Each mojo type needs to be manually defined.
// Example usage:
//    EXPECT_EQ(a, b) << GetDiffString(a, b);
//
// Example output:
//    field_a:
//       [Equal]
//    field_b:
//       "a value" vs "another value"
template <typename T>
std::string GetDiffString(const T& a, const T& b) {
  if (a == b)
    return internal::kEqualStr;
  if constexpr (IsStructPtr<T>::value) {
    if (a.is_null()) {
      return internal::StringCompareFormat(internal::kNullStr,
                                           internal::kNotNullStr);
    }
    if (b.is_null()) {
      return internal::StringCompareFormat(internal::kNotNullStr,
                                           internal::kNullStr);
    }
    return GetDiffString(*a, *b);
  } else if constexpr (std::is_enum_v<T>) {
    return GetDiffString("[Enum]:" + std::to_string(static_cast<int>(a)),
                         "[Enum]:" + std::to_string(static_cast<int>(b)));
  } else if constexpr (IsVector<T>::value) {  // NOLINT(readability/braces)
                                              // b/194872701
    if (a.size() != b.size()) {
      return internal::StringCompareFormat(
          "Vector[size: " + std::to_string(a.size()) + "]",
          "Vector[size: " + std::to_string(b.size()) + "]");
    }
    for (size_t i = 0; i < a.size(); ++i) {
      if (a[i] != b[i]) {
        return "Vector[" + std::to_string(i) + "]:\n" +
               internal::Indent(GetDiffString(a[i], b[i]));
      }
    }
    return internal::kEqualStr;
  } else if constexpr (std::is_arithmetic_v<T>) {
    return GetDiffString(std::to_string(a), std::to_string(b));
  } else {
    static_assert(UndefinedMojoType<T>::value,
                  "Undefined type for GetDiffString().");
  }
}

template <>
std::string GetDiffString<std::string>(const std::string& a,
                                       const std::string& b);

template <>
std::string GetDiffString<base::Optional<std::string>>(
    const base::Optional<std::string>& a, const base::Optional<std::string>& b);

template <>
std::string GetDiffString<::chromeos::cros_healthd::mojom::NullableUint64>(
    const ::chromeos::cros_healthd::mojom::NullableUint64& a,
    const ::chromeos::cros_healthd::mojom::NullableUint64& b);

template <>
std::string GetDiffString<::chromeos::cros_healthd::mojom::VpdInfo>(
    const ::chromeos::cros_healthd::mojom::VpdInfo& a,
    const ::chromeos::cros_healthd::mojom::VpdInfo& b);

template <>
std::string GetDiffString<::chromeos::cros_healthd::mojom::DmiInfo>(
    const ::chromeos::cros_healthd::mojom::DmiInfo& a,
    const ::chromeos::cros_healthd::mojom::DmiInfo& b);

template <>
std::string GetDiffString<::chromeos::cros_healthd::mojom::OsVersion>(
    const ::chromeos::cros_healthd::mojom::OsVersion& a,
    const ::chromeos::cros_healthd::mojom::OsVersion& b);

template <>
std::string GetDiffString<::chromeos::cros_healthd::mojom::OsInfo>(
    const ::chromeos::cros_healthd::mojom::OsInfo& a,
    const ::chromeos::cros_healthd::mojom::OsInfo& b);

template <>
std::string GetDiffString<::chromeos::cros_healthd::mojom::SystemInfoV2>(
    const ::chromeos::cros_healthd::mojom::SystemInfoV2& a,
    const ::chromeos::cros_healthd::mojom::SystemInfoV2& b);

template <>
std::string GetDiffString<::chromeos::cros_healthd::mojom::BusDevice>(
    const ::chromeos::cros_healthd::mojom::BusDevice& a,
    const ::chromeos::cros_healthd::mojom::BusDevice& b);

template <>
std::string GetDiffString<::chromeos::cros_healthd::mojom::BusInfo>(
    const ::chromeos::cros_healthd::mojom::BusInfo& a,
    const ::chromeos::cros_healthd::mojom::BusInfo& b);

template <>
std::string GetDiffString<::chromeos::cros_healthd::mojom::PciBusInfo>(
    const ::chromeos::cros_healthd::mojom::PciBusInfo& a,
    const ::chromeos::cros_healthd::mojom::PciBusInfo& b);

template <>
std::string GetDiffString<::chromeos::cros_healthd::mojom::UsbBusInfo>(
    const ::chromeos::cros_healthd::mojom::UsbBusInfo& a,
    const ::chromeos::cros_healthd::mojom::UsbBusInfo& b);

template <>
std::string GetDiffString<::chromeos::cros_healthd::mojom::UsbBusInterfaceInfo>(
    const ::chromeos::cros_healthd::mojom::UsbBusInterfaceInfo& a,
    const ::chromeos::cros_healthd::mojom::UsbBusInterfaceInfo& b);

// Clones and sorts the vector.
template <typename T, typename = std::enable_if_t<IsStructPtr<T>::value>>
std::vector<T> Sorted(const std::vector<T>& in) {
  std::vector<T> out;
  for (const auto& ele : in) {
    out.push_back(ele.Clone());
  }
  sort(out.begin(), out.end());
  return out;
}

}  // namespace diagnostics

#endif  // DIAGNOSTICS_COMMON_MOJO_TYPE_UTILS_H_
