// Copyright 2019 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_DEVICES_SYSMEM_DRIVERS_SYSMEM_UTILS_H_
#define SRC_DEVICES_SYSMEM_DRIVERS_SYSMEM_UTILS_H_

#include <fidl/fuchsia.sysmem/cpp/fidl.h>
#include <fidl/fuchsia.sysmem2/cpp/fidl.h>
#include <lib/sysmem-version/sysmem-version.h>

#include <type_traits>

#include <safemath/safe_conversions.h>

bool IsWriteUsage(const fuchsia_sysmem2::BufferUsage& buffer_usage);

bool IsCpuUsage(const fuchsia_sysmem2::BufferUsage& buffer_usage);

bool IsAnyUsage(const fuchsia_sysmem2::BufferUsage& buffer_usage);

namespace internal {

// Partial template specialization only works on classes / structs not functions, so impl is a
// struct.
//
// Base case lacks "do_cast" so intentionally won't compile.
template <typename TypeOut, typename TypeIn, typename Enable = void>
struct SafeCastImpl {};
template <typename TypeOut, typename TypeIn>
struct SafeCastImpl<
    TypeOut, TypeIn,
    std::enable_if_t<std::is_arithmetic_v<TypeOut> && std::is_arithmetic_v<TypeIn>>> {
  static constexpr TypeOut do_cast(TypeIn in) { return safemath::checked_cast<TypeOut>(in); }
};
template <typename TypeOut, typename TypeIn>
struct SafeCastImpl<
    TypeOut, TypeIn,
    std::enable_if_t<!std::is_arithmetic_v<TypeOut> || !std::is_arithmetic_v<TypeIn>>> {
  // We explicitly require any casting to/from fidl enum to be converting from/to the exact
  // underlying type, respectively.  Any additional conversion on top of that can be achieved with a
  // separate safe_cast<>().
  static_assert(!sysmem::IsFidlEnum_v<TypeOut> ||
                std::is_same_v<TypeIn, sysmem::FidlUnderlyingTypeOrType_t<TypeOut>>);
  static_assert(!sysmem::IsFidlEnum_v<TypeIn> ||
                std::is_same_v<TypeOut, sysmem::FidlUnderlyingTypeOrType_t<TypeIn>>);

  static constexpr TypeOut do_cast(TypeIn in) {
    if constexpr (sysmem::IsFidlEnum_v<TypeOut> || sysmem::IsFidlEnum_v<TypeIn>) {
      // LLCPP natural enums can be converted to/from their underlying type, but only explicitly.
      // Thanks to the static_assert()s above, we know that this static_cast<>() won't be narrowing
      // (or widening).
      return static_cast<TypeOut>(in);
    } else {
      // The -Wno-conversion cflags can only catch narrowing if the conversion is an implicit
      // conversion, so we need this to be an implicit conversion to cause any narrowing under this
      // template specialization to be a compile warning (treated as error).
      //
      // If hitting a compile warning about narrowing here, ensure that all narrowing safe_cast<>()s
      // are done with the source and destination types both is_arithmetic_v<> true.  This way, all
      // narrowing goes through safemath::checked_cast<>() above.  In other words, avoid doing both
      // a narrowing and a conversion to/from non-is_arithmetic_v<> in the same safe_cast<>().
      // Instead, do those two conversion steps separately, with separate safe_cast<>()s.
      return in;
    }
  }
};

}  // namespace internal

template <typename TypeOut, typename TypeIn>
constexpr TypeOut safe_cast(TypeIn in) {
  return internal::SafeCastImpl<TypeOut, TypeIn>::do_cast(in);
}

// debug_safe_cast<>() is _only_ for use in situations where we are very sure that
// safemath::checked_cast<>() would not ever complain.  The "safe"-ness is disabled in --release to
// avoid completely unnecessary checking in situations where the checking would be both very
// unnecessary and at least plausibly a performance concern.  Use safe_cast<>() instead in nearly
// all situations.  Buffer pattern filling is an example where debug_safe_cast<>() can be
// appropriate.
#if ZX_DEBUG_ASSERT_IMPLEMENTED
// This is "safe" in debug.  This way we can double-check when not --release that we're not messing
// up in a situation where we are "very sure" won't annoy safemath::checked_cast<>().
template <typename TypeOut, typename TypeIn>
constexpr TypeOut debug_safe_cast(TypeIn in) {
  return internal::SafeCastImpl<TypeOut, TypeIn>::do_cast(in);
}
#else
// Not "safe" in --release, but we only use debug_safe_cast<> when we're quite sure
// safemath::checked_cast<> can't possibly complain.
template <typename TypeOut, typename TypeIn>
constexpr TypeOut debug_safe_cast(TypeIn in) {
  return static_cast<TypeOut>(in);
}
#endif

// Ensure we get/permit a constexpr cast when possible.
static_assert(4u == safe_cast<uint32_t>(4ull));

template <typename FidlType, typename enable = void>
class IsNaturalFidlTable : public std::false_type {};
template <typename FidlType>
class IsNaturalFidlTable<
    FidlType, std::enable_if_t<fidl::IsTable<FidlType>::value && !fidl::IsWire<FidlType>::value>>
    : public std::true_type {};

static_assert(IsNaturalFidlTable<fuchsia_sysmem2::BufferUsage>::value);
static_assert(!IsNaturalFidlTable<fuchsia_sysmem2::wire::BufferUsage>::value);
static_assert(!IsNaturalFidlTable<uint32_t>::value);
static_assert(!IsNaturalFidlTable<std::vector<fuchsia_sysmem2::BufferUsage>>::value);
static_assert(!IsNaturalFidlTable<std::vector<fuchsia_sysmem::BufferUsage>>::value);
static_assert(!IsNaturalFidlTable<fidl::VectorView<fuchsia_sysmem::BufferUsage>>::value);
static_assert(!IsNaturalFidlTable<fidl::VectorView<fuchsia_sysmem2::BufferUsage>>::value);
static_assert(!IsNaturalFidlTable<std::string>::value);
static_assert(!IsNaturalFidlTable<fidl::StringView>::value);

template <typename T>
void ignore_result(const T& to_ignore) {}

template <typename TypeOut, typename TypeIn>
TypeOut static_down_cast(TypeIn in) {
  TypeOut result = static_cast<TypeOut>(in);
  // This doesn't guarantee that |in| is actually an instance of sub-class TypeOut, but it does at
  // least check that TypeOut is a sub-class of TypeIn.
  static_assert(std::is_base_of_v<std::remove_reference_t<decltype(*in)>,
                                  std::remove_reference_t<decltype(*result)>>);
  return result;
}

#endif  // SRC_DEVICES_SYSMEM_DRIVERS_SYSMEM_UTILS_H_
