// Copyright 2020 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 TOOLS_FIDL_FIDLC_INCLUDE_FIDL_DIAGNOSTIC_TYPES_H_
#define TOOLS_FIDL_FIDLC_INCLUDE_FIDL_DIAGNOSTIC_TYPES_H_

#include <cassert>
#include <set>
#include <sstream>
#include <string_view>

#include "source_span.h"
#include "token.h"

namespace fidl {

// Forward decls
namespace raw {
class Attribute;
class AttributeList;
}  // namespace raw

namespace flat {
struct Constant;
struct IdentifierConstant;
struct LiteralConstant;
struct TypeConstructor;
struct Type;
class TypeTemplate;
class Name;
}  // namespace flat

namespace diagnostics {
namespace internal {

constexpr std::string_view kFormatMarker = "{}";

std::string Display(const std::string& s);
std::string Display(std::string_view s);
std::string Display(const std::set<std::string>& s);
std::string Display(const SourceSpan& s);
std::string Display(const Token::KindAndSubkind& t);
std::string Display(const raw::Attribute& a);
std::string Display(const raw::AttributeList& a);
std::string Display(const std::vector<std::string_view>& library_name);
std::string Display(const flat::Constant* c);
std::string Display(const flat::TypeConstructor* tc);
std::string Display(const flat::Type* t);
std::string Display(const flat::TypeTemplate* t);
std::string Display(const flat::Name& n);
template <typename T, typename = decltype(std::to_string(std::declval<T>()))>
std::string Display(T val) {
  return std::to_string(val);
}

inline std::string FormatErr(std::string_view msg) {
  // This assert should never fail, because FormatErr is only called by
  // ReportError -- and calls to ReportError fail at compile time if the # of
  // args passed in != the number of args in the Error definition.
  assert(msg.find(kFormatMarker) == std::string::npos &&
         "number of format string parameters '{}' != number of supplied arguments");
  return std::string(msg);
}

template <typename T, typename... Rest>
std::string FormatErr(std::string_view msg, T t, Rest... rest) {
  size_t i = msg.find(kFormatMarker);
  // This assert should never fail (see non-template FormatErr)
  assert(i != std::string::npos &&
         "number of format string parameters '{}' != number of supplied arguments");

  // Split string at marker, insert formatted parameter
  std::stringstream s;
  s << msg.substr(0, i) << Display(t)
    << msg.substr(i + kFormatMarker.length(), msg.length() - i - kFormatMarker.length());

  return FormatErr(s.str(), rest...);
}

constexpr size_t count_format_args(std::string_view s) {
  size_t i = s.find(kFormatMarker, 0);
  size_t total = 0;
  while (i != std::string::npos && i < s.size()) {
    total++;
    i = s.find(kFormatMarker, i + kFormatMarker.size());
  }
  return total;
}

}  // namespace internal

struct DiagnosticDef {
  constexpr DiagnosticDef(std::string_view msg) : msg(msg) {}

  std::string_view msg;
};

// The definition of an error. All instances of ErrorDef are in diagnostics.h.
// Template args define format parameters in the error message.
template <typename... Args>
struct ErrorDef : DiagnosticDef {
  constexpr ErrorDef(std::string_view msg) : DiagnosticDef(msg) {
    // This can't be a static assert because msg is not constexpr.
    assert(sizeof...(Args) == internal::count_format_args(msg) &&
           "number of format string parameters '{}' != number of template arguments");
  }
};

// The definition of a warning. All instances of WarningDef are in
// diagnostics.h. Template args define format parameters in the warning message.
template <typename... Args>
struct WarningDef : DiagnosticDef {
  constexpr WarningDef(std::string_view msg) : DiagnosticDef(msg) {
    // This can't be a static assert because msg is not constexpr.
    assert(sizeof...(Args) == internal::count_format_args(msg) &&
           "number of format string parameters '{}' != number of template arguments");
  }
};

// A tag that indicates whether a diagnostic is an error or warning. In the
// future this could be extended to include hints, suggestions, etc.
enum class DiagnosticKind {
  kError,
  kWarning,
};

// Represents a given instance of an error. Points to the error type it is an
// instance of. Holds a SourceSpan indicating where the error occurred and a
// formatted error message, built from the ErrorDef's message template and
// format parameters passed in to Error's constructor.
// Exists in order to allow deferral of error reporting and to be able to pass
// around errors.
struct Diagnostic {
  Diagnostic(DiagnosticKind kind, const DiagnosticDef& err, const std::optional<SourceSpan>& span,
             const std::string msg)
      : kind(kind), err(err), span(span), msg(msg) {}
  Diagnostic(DiagnosticKind kind, const DiagnosticDef& err, const Token& token,
             const std::string msg)
      : kind(kind), err(err), span(token.span()), msg(msg) {}
  virtual ~Diagnostic() {}

  DiagnosticKind kind;
  const DiagnosticDef& err;
  std::optional<SourceSpan> span;
  std::string msg;
};

template <typename... Args>
struct Error : Diagnostic {
  Error(const ErrorDef<Args...>& err, std::optional<SourceSpan> span, Args... args)
      : Diagnostic(DiagnosticKind::kError, err, span, internal::FormatErr(err.msg, args...)) {}
};

template <typename... Args>
struct Warning : Diagnostic {
  Warning(const WarningDef<Args...>& warn, std::optional<SourceSpan> span, Args... args)
      : Diagnostic(DiagnosticKind::kWarning, warn, span, internal::FormatErr(warn.msg, args...)) {}
};

}  // namespace diagnostics
}  // namespace fidl

#endif  // TOOLS_FIDL_FIDLC_INCLUDE_FIDL_DIAGNOSTIC_TYPES_H_
