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

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

#include <chrono>
#include <cstddef> // IWYU pragma: keep
#include <ctime>
#include <ostream>
#include <stack>
#include <string>
#include <vector>

#include "cmXMLSafe.h"

class cmXMLWriter
{
public:
  cmXMLWriter(std::ostream& output, std::size_t level = 0);
  ~cmXMLWriter();

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

  void StartDocument(const char* encoding = "UTF-8");
  void EndDocument();

  void StartElement(std::string const& name);
  void EndElement();

  void BreakAttributes();

  template <typename T>
  void Attribute(const char* name, T const& value)
  {
    this->PreAttribute();
    this->Output << name << "=\"" << SafeAttribute(value) << '"';
  }

  void Element(const char* name);

  template <typename T>
  void Element(std::string const& name, T const& value)
  {
    this->StartElement(name);
    this->Content(value);
    this->EndElement();
  }

  template <typename T>
  void Content(T const& content)
  {
    this->PreContent();
    this->Output << SafeContent(content);
  }

  void Comment(const char* comment);

  void CData(std::string const& data);

  void Doctype(const char* doctype);

  void ProcessingInstruction(const char* target, const char* data);

  void FragmentFile(const char* fname);

  void SetIndentationElement(std::string const& element);

private:
  void ConditionalLineBreak(bool condition);

  void PreAttribute();
  void PreContent();

  void CloseStartElement();

private:
  static cmXMLSafe SafeAttribute(const char* value) { return { value }; }

  static cmXMLSafe SafeAttribute(std::string const& value)
  {
    return { value };
  }

  template <typename T>
  static T SafeAttribute(T value)
  {
    return value;
  }

  static cmXMLSafe SafeContent(const char* value)
  {
    return cmXMLSafe(value).Quotes(false);
  }

  static cmXMLSafe SafeContent(std::string const& value)
  {
    return cmXMLSafe(value).Quotes(false);
  }

  /*
   * Convert a std::chrono::system::time_point to the number of seconds since
   * the UN*X epoch.
   *
   * It would be tempting to convert a time_point to number of seconds by
   * using time_since_epoch(). Unfortunately the C++11 standard does not
   * specify what the epoch of the system_clock must be.
   * Therefore we must assume it is an arbitrary point in time. Instead of this
   * method, it is recommended to convert it by means of the to_time_t method.
   */
  static std::time_t SafeContent(
    std::chrono::system_clock::time_point const& value)
  {
    return std::chrono::system_clock::to_time_t(value);
  }

  template <typename T>
  static T SafeContent(T value)
  {
    return value;
  }

private:
  std::ostream& Output;
  std::stack<std::string, std::vector<std::string>> Elements;
  std::string IndentationElement;
  std::size_t Level;
  std::size_t Indent;
  bool ElementOpen;
  bool BreakAttrib;
  bool IsContent;
};

class cmXMLElement; // IWYU pragma: keep

class cmXMLDocument
{
public:
  cmXMLDocument(cmXMLWriter& xml)
    : xmlwr(xml)
  {
    xmlwr.StartDocument();
  }
  ~cmXMLDocument() { xmlwr.EndDocument(); }
  cmXMLDocument(const cmXMLDocument&) = delete;
  cmXMLDocument& operator=(const cmXMLDocument&) = delete;

private:
  friend class cmXMLElement;
  cmXMLWriter& xmlwr;
};

class cmXMLElement
{
public:
  cmXMLElement(cmXMLWriter& xml, const char* tag)
    : xmlwr(xml)
  {
    xmlwr.StartElement(tag);
  }
  cmXMLElement(cmXMLElement& par, const char* tag)
    : xmlwr(par.xmlwr)
  {
    xmlwr.StartElement(tag);
  }
  cmXMLElement(cmXMLDocument& doc, const char* tag)
    : xmlwr(doc.xmlwr)
  {
    xmlwr.StartElement(tag);
  }
  ~cmXMLElement() { xmlwr.EndElement(); }

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

  template <typename T>
  cmXMLElement& Attribute(const char* name, T const& value)
  {
    xmlwr.Attribute(name, value);
    return *this;
  }
  template <typename T>
  void Content(T const& content)
  {
    xmlwr.Content(content);
  }
  template <typename T>
  void Element(std::string const& name, T const& value)
  {
    xmlwr.Element(name, value);
  }
  void Comment(const char* comment) { xmlwr.Comment(comment); }

private:
  cmXMLWriter& xmlwr;
};
