// 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_UI_LIB_ESCHER_TEST_COMMON_VK_VK_DEBUG_REPORT_COLLECTOR_H_
#define SRC_UI_LIB_ESCHER_TEST_COMMON_VK_VK_DEBUG_REPORT_COLLECTOR_H_

#include <string>
#include <vector>

#include <vulkan/vulkan.hpp>

namespace escher::test {
namespace impl {

// Collects Vulkan debug reports and provides functions used by validation debug report checking
// macros.
//
// A test fixture which has an instance of |VkDebugReportCallbackRegistry| and
// |VkDebugReportCollector| will be able to store all validation debug reports by setting
// |HandleDebugReport| with |pUserData| pointing to this instance, as its callback function.
//
// NOTE: Users may want to use the test fixture class |TestWithVkValidationLayer| directly if they
// only need the basic unit tests with Vulkan validation layer enabled.
//
class VkDebugReportCollector {
 public:
  // Debug report struct generated by Vulkan validation layer.
  struct VkDebugReport {
    vk::DebugReportFlagsEXT flags;
    vk::DebugReportObjectTypeEXT object_type;
    uint64_t object;
    std::string layer_prefix;
    int32_t message_code;
    std::string message;

    std::string ErrorMessage() const {
      return "[" + vk::to_string(flags) + "] " + " [Object type] " + vk::to_string(object_type) +
             " [Object id] " + std::to_string(object) + " [Layer] " + layer_prefix +
             " [Message] # " + std::to_string(message_code) + " : " + message;
    }
  };

  // Default constructor.
  VkDebugReportCollector() = default;

  // Default Validation layer debug handler which stores all debug reports to the
  // std::vector<VkDebugReport> object which |pUserData|points to.
  //
  // The callback function is specified in
  // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/
  // PFN_vkDebugReportCallbackEXT.html
  //   |flags|        specifies the VkDebugReportFlagBitsEXT that triggered this callback.
  //   |object_type|  specifyins the type of object being used or created at the time the event was
  //                  triggered.
  //   |object|       is the object where the issue was detected.
  //   |location|     is a component (layer, driver, loader) defined value specifying the location
  //                  of the trigger. This is an optional value.
  //   |message_code| is a layer-defined value indicating what test triggered this callback.
  //   |layer_prefix| is a null-terminated string that is an abbreviation of the name of
  //                  the component making the callback.
  //   |message|      is a null-terminated string detailing the trigger conditions.
  //   |user_data|    is specified when user creates the debug callback object.
  static uint32_t HandleDebugReport(VkFlags flags, VkDebugReportObjectTypeEXT object_type,
                                    uint64_t object, size_t location, int32_t message_code,
                                    const char* layer_prefix, const char* message, void* user_data);

  // Print all debug reports with given flags. If there is no debug reports with that given flags
  // it will do nothing and return false; otherwise it returns true.
  // |file| and |line| are passed by macros using __FILE__ and __LINE__ to print error position.
  bool PrintDebugReportsWithFlags(const vk::DebugReportFlagsEXT& flags, const char* file,
                                  size_t line);

  // Helper function which prints out the debug reports if
  // |predicate|(number of debug reports with |flags|, |num_threshold|) == false.
  // |file| and |line| are passed by macros using __FILE__ and __LINE__ to print error position.
  //
  // Used only by |EXPECT/ASSERT_VULKAN_VALIDATION_LAYER_ERRORS_[PREDICATE]()| macros and should
  // only be called within test scope.
  bool PrintDebugReportsOnFalsePredicate(const vk::DebugReportFlagsEXT& flags, size_t num_threshold,
                                         const std::function<bool(size_t, size_t)>& predicate,
                                         const char* file, size_t line) const;

  // Removes debug reports with certain debug report flag from |debug_reports_| list to suppress
  // test failure.
  // Used by SUPPRESS_VK_VALIDATION_[WARNINGS/ERRORS/PERFORMANCE_WARNINGS]() macros and should
  // only be called within test scope..
  void SuppressDebugReportsWithFlag(const vk::DebugReportFlagsEXT& flags);

  // Removes all debug reports from |debug_reports_| list to suppress test failure.
  // Used by SUPPRESS_VK_VALIDATION_DEBUG_REPORTS() macro and should only be called within test
  // scope.
  void SuppressAllDebugReports() { SuppressDebugReportsWithFlag(~vk::DebugReportFlagsEXT()); }

 private:
  // Helper function which outputs all debug reports with specific flag.
  std::vector<VkDebugReport> DebugReportsWithFlag(const vk::DebugReportFlagsEXT& flags) const;

  std::vector<VkDebugReport> debug_reports_ = {};
};

}  // namespace impl
}  // namespace escher::test
#endif  // SRC_UI_LIB_ESCHER_TEST_COMMON_VK_VK_DEBUG_REPORT_COLLECTOR_H_
