/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2022,  Regents of the University of California,
 *                           Arizona Board of Regents,
 *                           Colorado State University,
 *                           University Pierre & Marie Curie, Sorbonne University,
 *                           Washington University in St. Louis,
 *                           Beijing Institute of Technology,
 *                           The University of Memphis.
 *
 * This file is part of NFD (Named Data Networking Forwarding Daemon).
 * See AUTHORS.md for complete list of NFD authors and contributors.
 *
 * NFD is free software: you can redistribute it and/or modify it under the terms
 * of the GNU General Public License as published by the Free Software Foundation,
 * either version 3 of the License, or (at your option) any later version.
 *
 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE.  See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef NFD_TOOLS_NFDC_FORMAT_HELPERS_HPP
#define NFD_TOOLS_NFDC_FORMAT_HELPERS_HPP

#include "core/common.hpp"

namespace nfd::tools::nfdc {

namespace xml {

void
printHeader(std::ostream& os);

void
printFooter(std::ostream& os);

struct Text
{
  const std::string& s;
};

/** \brief print XML text with special character represented as predefined entities
 */
std::ostream&
operator<<(std::ostream& os, const Text& text);

/** \brief print true as an empty element and false as nothing
 */
struct Flag
{
  const char* elementName;
  bool flag;
};

std::ostream&
operator<<(std::ostream& os, Flag v);

/** \return duration in XML duration format
 *
 *  Definition of this format: https://www.w3.org/TR/xmlschema11-2/#duration
 */
std::string
formatDuration(time::nanoseconds d);

/** \return timestamp in XML dateTime format
 *
 *  Definition of this format: https://www.w3.org/TR/xmlschema11-2/#dateTime
 */
std::string
formatTimestamp(time::system_clock::time_point t);

} // namespace xml

namespace text {

/** \brief print a number of whitespaces
 */
struct Spaces
{
  int nSpaces; ///< number of spaces; print nothing if negative
};

std::ostream&
operator<<(std::ostream& os, const Spaces& spaces);

/** \brief print different string on first and subsequent usage
 *
 *  \code
 *  Separator sep(",");
 *  for (int i = 1; i <= 3; ++i) {
 *    os << sep << i;
 *  }
 *  // prints: 1,2,3
 *  \endcode
 */
class Separator : noncopyable
{
public:
  Separator(std::string_view first, std::string_view subsequent);

  explicit
  Separator(std::string_view subsequent);

  int
  getCount() const
  {
    return m_count;
  }

private:
  const std::string m_first;
  const std::string m_subsequent;
  int m_count = 0;

  friend std::ostream& operator<<(std::ostream& os, Separator& sep);
};

std::ostream&
operator<<(std::ostream& os, Separator& sep);

/** \brief print attributes of an item
 *
 *  \code
 *  ItemAttributes ia(wantMultiLine, 3);
 *  os << ia("id") << 500
 *     << ia("uri") << "udp4://192.0.2.1:6363"
 *     << ia.end();
 *
 *  // prints in single-line style (wantMultiLine==false):
 *  // id=500 uri=udp4://192.0.2.1:6363 [no-newline]
 *
 *  // prints in multi-line style (wantMultiLine==true):
 *  //  id=500
 *  // uri=udp4://192.0.2.1:6363 [newline]
 *  \endcode
 */
class ItemAttributes : noncopyable
{
public:
  /** \brief constructor
   *  \param wantMultiLine true to select multi-line style, false to use single-line style
   *  \param maxAttributeWidth maximum width of attribute names, for alignment in multi-line style
   */
  explicit
  ItemAttributes(bool wantMultiLine = false, int maxAttributeWidth = 0);

  struct Attribute
  {
    ItemAttributes& ia;
    std::string attribute;
  };

  /** \note Caller must ensure ItemAttributes object is alive until after all Attribute objects are
   *        destructed.
   */
  Attribute
  operator()(const std::string& attribute);

  std::string
  end() const;

private:
  const bool m_wantMultiLine;
  const int m_maxAttributeWidth;
  int m_count = 0;

  friend std::ostream& operator<<(std::ostream& os, const ItemAttributes::Attribute& attr);
};

std::ostream&
operator<<(std::ostream& os, const ItemAttributes::Attribute& attr);

/** \brief print boolean as 'on' or 'off'
 */
struct OnOff
{
  bool flag;
};

std::ostream&
operator<<(std::ostream& os, OnOff v);

/** \brief print boolean as 'yes' or 'no'
 */
struct YesNo
{
  bool flag;
};

std::ostream&
operator<<(std::ostream& os, YesNo v);

namespace detail {

template<typename DurationT>
std::string
getTimeUnit(bool isLong);

template<>
inline std::string
getTimeUnit<time::nanoseconds>(bool isLong)
{
  return isLong ? "nanoseconds" : "ns";
}

template<>
inline std::string
getTimeUnit<time::microseconds>(bool isLong)
{
  return isLong ? "microseconds" : "us";
}

template<>
inline std::string
getTimeUnit<time::milliseconds>(bool isLong)
{
  return isLong ? "milliseconds" : "ms";
}

template<>
inline std::string
getTimeUnit<time::seconds>(bool isLong)
{
  return isLong ? "seconds" : "s";
}

template<>
inline std::string
getTimeUnit<time::minutes>(bool isLong)
{
  return isLong ? "minutes" : "m";
}

template<>
inline std::string
getTimeUnit<time::hours>(bool isLong)
{
  return isLong ? "hours" : "h";
}

template<>
inline std::string
getTimeUnit<time::days>(bool isLong)
{
  return isLong ? "days" : "d";
}

} // namespace detail

template<typename OutputPrecision>
std::string
formatDuration(time::nanoseconds d, bool isLong = false)
{
  return to_string(time::duration_cast<OutputPrecision>(d).count()) +
         (isLong ? " " : "") + detail::getTimeUnit<OutputPrecision>(isLong);
}

std::string
formatTimestamp(time::system_clock::time_point t);

} // namespace text

} // namespace nfd::tools::nfdc

#endif // NFD_TOOLS_NFDC_FORMAT_HELPERS_HPP
