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

#ifndef SRC_DEBUG_H_
#define SRC_DEBUG_H_

#include <utility>

#include "src/diagnostic/diagnostic.h"
#include "src/diagnostic/formatter.h"
#include "src/diagnostic/printer.h"

namespace tint {

/// Function type used for registering an internal compiler error reporter
using InternalCompilerErrorReporter = void(const diag::List&);

/// Sets the global error reporter to be called in case of internal compiler
/// errors.
/// @param reporter the error reporter
void SetInternalCompilerErrorReporter(InternalCompilerErrorReporter* reporter);

/// InternalCompilerError is a helper for reporting internal compiler errors.
/// Construct the InternalCompilerError with the source location of the ICE
/// fault and append any error details with the `<<` operator.
/// When the InternalCompilerError is destructed, the concatenated error message
/// is appended to the diagnostics list with the severity of
/// tint::diag::Severity::InternalCompilerError, and if a
/// InternalCompilerErrorReporter is set, then it is called with the diagnostic
/// list.
class InternalCompilerError {
 public:
  /// Constructor
  /// @param file the file containing the ICE
  /// @param line the line containing the ICE
  /// @param system the Tint system that has raised the ICE
  /// @param diagnostics the list of diagnostics to append the ICE message to
  InternalCompilerError(const char* file,
                        size_t line,
                        diag::System system,
                        diag::List& diagnostics);

  /// Destructor.
  /// Adds the internal compiler error message to the diagnostics list, and then
  /// calls the InternalCompilerErrorReporter if one is set.
  ~InternalCompilerError();

  /// Appends `arg` to the ICE message.
  /// @param arg the argument to append to the ICE message
  /// @returns this object so calls can be chained
  template <typename T>
  InternalCompilerError& operator<<(T&& arg) {
    msg_ << std::forward<T>(arg);
    return *this;
  }

 private:
  char const* const file_;
  const size_t line_;
  diag::System system_;
  diag::List& diagnostics_;
  std::stringstream msg_;
};

}  // namespace tint

/// TINT_ICE() is a macro for appending an internal compiler error message
/// to the diagnostics list `diagnostics`, and calling the
/// InternalCompilerErrorReporter with the full diagnostic list if a reporter is
/// set.
/// The ICE message contains the callsite's file and line.
/// Use the `<<` operator to append an error message to the ICE.
#define TINT_ICE(system, diagnostics)             \
  tint::InternalCompilerError(__FILE__, __LINE__, \
                              ::tint::diag::System::system, diagnostics)

/// TINT_UNREACHABLE() is a macro for appending a "TINT_UNREACHABLE"
/// internal compiler error message to the diagnostics list `diagnostics`, and
/// calling the InternalCompilerErrorReporter with the full diagnostic list if a
/// reporter is set.
/// The ICE message contains the callsite's file and line.
/// Use the `<<` operator to append an error message to the ICE.
#define TINT_UNREACHABLE(system, diagnostics) \
  TINT_ICE(system, diagnostics) << "TINT_UNREACHABLE "

/// TINT_UNIMPLEMENTED() is a macro for appending a "TINT_UNIMPLEMENTED"
/// internal compiler error message to the diagnostics list `diagnostics`, and
/// calling the InternalCompilerErrorReporter with the full diagnostic list if a
/// reporter is set.
/// The ICE message contains the callsite's file and line.
/// Use the `<<` operator to append an error message to the ICE.
#define TINT_UNIMPLEMENTED(system, diagnostics) \
  TINT_ICE(system, diagnostics) << "TINT_UNIMPLEMENTED "

/// TINT_ASSERT() is a macro for checking the expression is true, triggering a
/// TINT_ICE if it is not.
/// The ICE message contains the callsite's file and line.
/// @warning: Unlike TINT_ICE() and TINT_UNREACHABLE(), TINT_ASSERT() does not
/// append a message to an existing tint::diag::List. As such, TINT_ASSERT()
/// may silently fail in builds where SetInternalCompilerErrorReporter() is not
/// called. Only use in places where there's no sensible place to put proper
/// error handling.
#define TINT_ASSERT(system, condition)                   \
  do {                                                   \
    if (!(condition)) {                                  \
      tint::diag::List diagnostics;                      \
      TINT_ICE(system, diagnostics)                      \
          << "TINT_ASSERT(" #system ", " #condition ")"; \
    }                                                    \
  } while (false)

#endif  // SRC_DEBUG_H_
