/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#ifndef cmCPackLog_h
#define cmCPackLog_h

#include "cmConfigure.h" // IWYU pragma: keep

#include <ostream>
#include <string>

#include <string.h>

#define cmCPack_Log(ctSelf, logType, msg)                                     \
  do {                                                                        \
    std::ostringstream cmCPackLog_msg;                                        \
    cmCPackLog_msg << msg;                                                    \
    (ctSelf)->Log(logType, __FILE__, __LINE__, cmCPackLog_msg.str().c_str()); \
  } while (false)

/** \class cmCPackLog
 * \brief A container for CPack generators
 *
 */
class cmCPackLog
{
public:
  cmCPackLog();
  ~cmCPackLog();

  cmCPackLog(const cmCPackLog&) = delete;
  cmCPackLog& operator=(const cmCPackLog&) = delete;

  enum __log_tags
  {
    NOTAG = 0,
    LOG_OUTPUT = 0x1,
    LOG_VERBOSE = 0x2,
    LOG_DEBUG = 0x4,
    LOG_WARNING = 0x8,
    LOG_ERROR = 0x10
  };

  //! Various signatures for logging.
  void Log(const char* file, int line, const char* msg)
  {
    this->Log(LOG_OUTPUT, file, line, msg);
  }
  void Log(const char* file, int line, const char* msg, size_t length)
  {
    this->Log(LOG_OUTPUT, file, line, msg, length);
  }
  void Log(int tag, const char* file, int line, const char* msg)
  {
    this->Log(tag, file, line, msg, strlen(msg));
  }
  void Log(int tag, const char* file, int line, const char* msg,
           size_t length);

  //! Set Verbose
  void VerboseOn() { this->SetVerbose(true); }
  void VerboseOff() { this->SetVerbose(true); }
  void SetVerbose(bool verb) { this->Verbose = verb; }
  bool GetVerbose() { return this->Verbose; }

  //! Set Debug
  void DebugOn() { this->SetDebug(true); }
  void DebugOff() { this->SetDebug(true); }
  void SetDebug(bool verb) { this->Debug = verb; }
  bool GetDebug() { return this->Debug; }

  //! Set Quiet
  void QuietOn() { this->SetQuiet(true); }
  void QuietOff() { this->SetQuiet(true); }
  void SetQuiet(bool verb) { this->Quiet = verb; }
  bool GetQuiet() { return this->Quiet; }

  //! Set the output stream
  void SetOutputStream(std::ostream* os) { this->DefaultOutput = os; }

  //! Set the error stream
  void SetErrorStream(std::ostream* os) { this->DefaultError = os; }

  //! Set the log output stream
  void SetLogOutputStream(std::ostream* os);

  //! Set the log output file. The cmCPackLog will try to create file. If it
  // cannot, it will report an error.
  bool SetLogOutputFile(const char* fname);

  //! Set the various prefixes for the logging. SetPrefix sets the generic
  // prefix that overwrites missing ones.
  void SetPrefix(std::string const& pfx) { this->Prefix = pfx; }
  void SetOutputPrefix(std::string const& pfx) { this->OutputPrefix = pfx; }
  void SetVerbosePrefix(std::string const& pfx) { this->VerbosePrefix = pfx; }
  void SetDebugPrefix(std::string const& pfx) { this->DebugPrefix = pfx; }
  void SetWarningPrefix(std::string const& pfx) { this->WarningPrefix = pfx; }
  void SetErrorPrefix(std::string const& pfx) { this->ErrorPrefix = pfx; }

private:
  bool Verbose;
  bool Debug;
  bool Quiet;

  bool NewLine;

  int LastTag;

  std::string Prefix;
  std::string OutputPrefix;
  std::string VerbosePrefix;
  std::string DebugPrefix;
  std::string WarningPrefix;
  std::string ErrorPrefix;

  std::ostream* DefaultOutput;
  std::ostream* DefaultError;

  std::string LogOutputFileName;
  std::ostream* LogOutput;
  // Do we need to cleanup log output stream
  bool LogOutputCleanup;
};

class cmCPackLogWrite
{
public:
  cmCPackLogWrite(const char* data, size_t length)
    : Data(data)
    , Length(length)
  {
  }

  const char* Data;
  size_t Length;
};

inline std::ostream& operator<<(std::ostream& os, const cmCPackLogWrite& c)
{
  os.write(c.Data, c.Length);
  os.flush();
  return os;
}

#endif
