//===-- include/flang/Parser/message.h --------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef FORTRAN_PARSER_MESSAGE_H_
#define FORTRAN_PARSER_MESSAGE_H_

// Defines a representation for sequences of compiler messages.
// Supports nested contextualization.

#include "char-block.h"
#include "char-set.h"
#include "provenance.h"
#include "flang/Common/idioms.h"
#include "flang/Common/reference-counted.h"
#include "flang/Common/restorer.h"
#include <cstddef>
#include <cstring>
#include <forward_list>
#include <list>
#include <optional>
#include <string>
#include <utility>
#include <variant>

namespace Fortran::parser {

// Use "..."_err_en_US and "..."_en_US literals to define the static
// text and fatality of a message.
class MessageFixedText {
public:
  constexpr MessageFixedText(
      const char str[], std::size_t n, bool isFatal = false)
      : text_{str, n}, isFatal_{isFatal} {}
  constexpr MessageFixedText(const MessageFixedText &) = default;
  constexpr MessageFixedText(MessageFixedText &&) = default;
  constexpr MessageFixedText &operator=(const MessageFixedText &) = default;
  constexpr MessageFixedText &operator=(MessageFixedText &&) = default;

  CharBlock text() const { return text_; }
  bool isFatal() const { return isFatal_; }

private:
  CharBlock text_;
  bool isFatal_{false};
};

inline namespace literals {
constexpr MessageFixedText operator""_en_US(const char str[], std::size_t n) {
  return MessageFixedText{str, n, false /* not fatal */};
}

constexpr MessageFixedText operator""_err_en_US(
    const char str[], std::size_t n) {
  return MessageFixedText{str, n, true /* fatal */};
}
} // namespace literals

// The construction of a MessageFormattedText uses a MessageFixedText
// as a vsnprintf() formatting string that is applied to the
// following arguments.  CharBlock and std::string argument
// values are also supported; they are automatically converted into
// char pointers that are suitable for '%s' formatting.
class MessageFormattedText {
public:
  template <typename... A>
  MessageFormattedText(const MessageFixedText &text, A &&...x)
      : isFatal_{text.isFatal()} {
    Format(&text, Convert(std::forward<A>(x))...);
  }
  MessageFormattedText(const MessageFormattedText &) = default;
  MessageFormattedText(MessageFormattedText &&) = default;
  MessageFormattedText &operator=(const MessageFormattedText &) = default;
  MessageFormattedText &operator=(MessageFormattedText &&) = default;
  const std::string &string() const { return string_; }
  bool isFatal() const { return isFatal_; }
  std::string MoveString() { return std::move(string_); }

private:
  void Format(const MessageFixedText *, ...);

  template <typename A> A Convert(const A &x) {
    static_assert(!std::is_class_v<std::decay_t<A>>);
    return x;
  }
  template <typename A> A Convert(A &x) {
    static_assert(!std::is_class_v<std::decay_t<A>>);
    return x;
  }
  template <typename A> common::IfNoLvalue<A, A> Convert(A &&x) {
    static_assert(!std::is_class_v<std::decay_t<A>>);
    return std::move(x);
  }
  const char *Convert(const char *s) { return s; }
  const char *Convert(char *s) { return s; }
  const char *Convert(const std::string &);
  const char *Convert(std::string &);
  const char *Convert(std::string &&);
  const char *Convert(CharBlock);
  std::intmax_t Convert(std::int64_t x) { return x; }
  std::uintmax_t Convert(std::uint64_t x) { return x; }

  bool isFatal_{false};
  std::string string_;
  std::forward_list<std::string> conversions_; // preserves created strings
};

// Represents a formatted rendition of "expected '%s'"_err_en_US
// on a constant text or a set of characters.
class MessageExpectedText {
public:
  MessageExpectedText(const char *s, std::size_t n) {
    if (n == std::string::npos) {
      n = std::strlen(s);
    }
    if (n == 1) {
      // Treat a one-character string as a singleton set for better merging.
      u_ = SetOfChars{*s};
    } else {
      u_ = CharBlock{s, n};
    }
  }
  constexpr explicit MessageExpectedText(CharBlock cb) : u_{cb} {}
  constexpr explicit MessageExpectedText(char ch) : u_{SetOfChars{ch}} {}
  constexpr explicit MessageExpectedText(SetOfChars set) : u_{set} {}
  MessageExpectedText(const MessageExpectedText &) = default;
  MessageExpectedText(MessageExpectedText &&) = default;
  MessageExpectedText &operator=(const MessageExpectedText &) = default;
  MessageExpectedText &operator=(MessageExpectedText &&) = default;

  std::string ToString() const;
  bool Merge(const MessageExpectedText &);

private:
  std::variant<CharBlock, SetOfChars> u_;
};

class Message : public common::ReferenceCounted<Message> {
public:
  using Reference = common::CountedReference<Message>;

  Message(const Message &) = default;
  Message(Message &&) = default;
  Message &operator=(const Message &) = default;
  Message &operator=(Message &&) = default;

  Message(ProvenanceRange pr, const MessageFixedText &t)
      : location_{pr}, text_{t} {}
  Message(ProvenanceRange pr, const MessageFormattedText &s)
      : location_{pr}, text_{s} {}
  Message(ProvenanceRange pr, MessageFormattedText &&s)
      : location_{pr}, text_{std::move(s)} {}
  Message(ProvenanceRange pr, const MessageExpectedText &t)
      : location_{pr}, text_{t} {}

  Message(CharBlock csr, const MessageFixedText &t)
      : location_{csr}, text_{t} {}
  Message(CharBlock csr, const MessageFormattedText &s)
      : location_{csr}, text_{s} {}
  Message(CharBlock csr, MessageFormattedText &&s)
      : location_{csr}, text_{std::move(s)} {}
  Message(CharBlock csr, const MessageExpectedText &t)
      : location_{csr}, text_{t} {}

  template <typename RANGE, typename A, typename... As>
  Message(RANGE r, const MessageFixedText &t, A &&x, As &&...xs)
      : location_{r}, text_{MessageFormattedText{
                          t, std::forward<A>(x), std::forward<As>(xs)...}} {}

  bool attachmentIsContext() const { return attachmentIsContext_; }
  Reference attachment() const { return attachment_; }

  void SetContext(Message *c) {
    attachment_ = c;
    attachmentIsContext_ = true;
  }
  Message &Attach(Message *);
  Message &Attach(std::unique_ptr<Message> &&);
  template <typename... A> Message &Attach(A &&...args) {
    return Attach(new Message{std::forward<A>(args)...}); // reference-counted
  }

  bool SortBefore(const Message &that) const;
  bool IsFatal() const;
  std::string ToString() const;
  std::optional<ProvenanceRange> GetProvenanceRange(
      const AllCookedSources &) const;
  void Emit(llvm::raw_ostream &, const AllCookedSources &,
      bool echoSourceLine = true) const;

  // If this Message or any of its attachments locates itself via a CharBlock,
  // replace its location with the corresponding ProvenanceRange.
  void ResolveProvenances(const AllCookedSources &);

  bool IsMergeable() const {
    return std::holds_alternative<MessageExpectedText>(text_);
  }
  bool Merge(const Message &);

private:
  bool AtSameLocation(const Message &) const;

  std::variant<ProvenanceRange, CharBlock> location_;
  std::variant<MessageFixedText, MessageFormattedText, MessageExpectedText>
      text_;
  bool attachmentIsContext_{false};
  Reference attachment_;
};

class Messages {
public:
  Messages() {}
  Messages(Messages &&that) : messages_{std::move(that.messages_)} {}
  Messages &operator=(Messages &&that) {
    messages_ = std::move(that.messages_);
    return *this;
  }

  std::list<Message> &messages() { return messages_; }
  bool empty() const { return messages_.empty(); }
  void clear() { messages_.clear(); }

  template <typename... A> Message &Say(A &&...args) {
    return messages_.emplace_back(std::forward<A>(args)...);
  }

  void Annex(Messages &&that) {
    messages_.splice(messages_.end(), that.messages_);
  }

  bool Merge(const Message &);
  void Merge(Messages &&);
  void Copy(const Messages &);
  void ResolveProvenances(const AllCookedSources &);
  void Emit(llvm::raw_ostream &, const AllCookedSources &,
      bool echoSourceLines = true) const;
  void AttachTo(Message &);
  bool AnyFatalError() const;

private:
  std::list<Message> messages_;
};

class ContextualMessages {
public:
  ContextualMessages() = default;
  ContextualMessages(CharBlock at, Messages *m) : at_{at}, messages_{m} {}
  explicit ContextualMessages(Messages *m) : messages_{m} {}
  ContextualMessages(const ContextualMessages &that)
      : at_{that.at_}, messages_{that.messages_} {}

  CharBlock at() const { return at_; }
  Messages *messages() const { return messages_; }
  Message::Reference contextMessage() const { return contextMessage_; }
  bool empty() const { return !messages_ || messages_->empty(); }

  // Set CharBlock for messages; restore when the returned value is deleted
  common::Restorer<CharBlock> SetLocation(CharBlock at) {
    if (at.empty()) {
      at = at_;
    }
    return common::ScopedSet(at_, std::move(at));
  }

  common::Restorer<Message::Reference> SetContext(Message *m) {
    if (!m) {
      m = contextMessage_.get();
    }
    return common::ScopedSet(contextMessage_, m);
  }

  // Diverts messages to another buffer; restored when the returned
  // value is deleted.
  common::Restorer<Messages *> SetMessages(Messages &buffer) {
    return common::ScopedSet(messages_, &buffer);
  }
  // Discard future messages until the returned value is deleted.
  common::Restorer<Messages *> DiscardMessages() {
    return common::ScopedSet(messages_, nullptr);
  }

  template <typename... A> Message *Say(CharBlock at, A &&...args) {
    if (messages_ != nullptr) {
      auto &msg{messages_->Say(at, std::forward<A>(args)...)};
      if (contextMessage_) {
        msg.SetContext(contextMessage_.get());
      }
      return &msg;
    } else {
      return nullptr;
    }
  }

  template <typename... A> Message *Say(A &&...args) {
    return Say(at_, std::forward<A>(args)...);
  }

private:
  CharBlock at_;
  Messages *messages_{nullptr};
  Message::Reference contextMessage_;
};
} // namespace Fortran::parser
#endif // FORTRAN_PARSER_MESSAGE_H_
