/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2013-2022 Regents of the University of California.
 *
 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
 *
 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * ndn-cxx library 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 Lesser General Public License for more details.
 *
 * You should have received copies of the GNU General Public License and GNU Lesser
 * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
 */

#ifndef NDN_CXX_SECURITY_TRANSFORM_BASE_HPP
#define NDN_CXX_SECURITY_TRANSFORM_BASE_HPP

#include "ndn-cxx/detail/common.hpp"
#include "ndn-cxx/util/span.hpp"

#include <vector>

namespace ndn {
namespace security {
namespace transform {

/**
 * @file
 *
 * There are three types of module in a transformation chain: Source, Transform, and Sink.
 * The ideal usage of the transformation would be:
 *
 *   source(...) >> transform1(...) >> transform2(...) >> sink(...);
 *
 * When error happens in a module, the module will throw out a transform::Error, one
 * can get the location of the module through the getIndex() method of transform::Error.
 */

/**
 * @brief Base class of transformation error
 */
class Error : public std::runtime_error
{
public:
  Error(size_t index, const std::string& what);

  size_t
  getIndex() const
  {
    return m_index;
  }

private:
  size_t m_index;
};

/**
 * @brief The downstream interface of a transformation module.
 *
 * A module can accept input through this interface.
 */
class Downstream : noncopyable
{
public:
  virtual
  ~Downstream() = default;

  /**
   * @brief Accept input data and perform transformation.
   *
   * An upstream module should call this method to write data into this module.
   * The written data will be transformed and the result will be written into the next
   * downstream module.
   *
   * An upstream module can keep calling this method to until end() is called, which
   * indicates the end of input.  After that, calling this method will cause Error.
   *
   * If a Downstream implementation expects structured input (e.g., hex decoding requires byte-pair),
   * it should not return less than size if final portion of input is not a complete record.
   *
   * @return Number of bytes that have been written into this module.
   * @throws Error if this module is closed or transformation error happens.
   */
  size_t
  write(span<const uint8_t> buf);

  /**
   * @brief Close the input interface of a module.
   *
   * This method will notify this module that there is no more input and that the module
   * should finalize transformation.
   *
   * Although end() can be invoked multiple times, only the first invocation takes effect.
   */
  void
  end();

  /**
   * @brief Check if the input interface of a module is closed.
   */
  bool
  isEnd() const
  {
    return m_isEnd;
  }

  /**
   * @brief Set the module index.
   */
  void
  setIndex(size_t index)
  {
    m_index = index;
  }

  /**
   * @brief Get the module index.
   */
  size_t
  getIndex() const
  {
    return m_index;
  }

protected:
  Downstream() = default;

private:
  virtual size_t
  doWrite(span<const uint8_t> buf) = 0;

  virtual void
  doEnd() = 0;

private:
  size_t m_index = 0;
  bool m_isEnd = false;
};

/**
 * @brief The upstream interface of a transformation module.
 *
 * A module can construct subsequent transformation chains through this interface.
 */
class Upstream
{
public:
  virtual
  ~Upstream() = default;

protected:
  Upstream() = default;

  /**
   * @brief Connect to the next transformation module
   */
  void
  appendChain(unique_ptr<Downstream> tail);

  Downstream*
  getNext()
  {
    return m_next.get();
  }

protected:
  unique_ptr<Downstream> m_next;
};

/**
 * @brief Abstraction of an intermediate transformation module.
 */
class Transform : public Upstream,
                  public Downstream
{
protected:
  using OBuffer = std::vector<uint8_t>;

  Transform() = default;

  /**
   * @brief Read the content from output buffer and write it into next module.
   *
   * It is not guaranteed that all the content in output buffer will be flushed to next module.
   */
  void
  flushOutputBuffer();

  /**
   * @brief Read the all the content from output buffer and write it into next module.
   * @post isOutputBufferEmpty() returns true.
   */
  void
  flushAllOutput();

  /**
   * @brief Set output buffer to @p buffer
   */
  void
  setOutputBuffer(unique_ptr<OBuffer> buffer);

  /**
   * @brief Check if output buffer is empty
   */
  bool
  isOutputBufferEmpty() const;

private:
  size_t
  doWrite(span<const uint8_t> data) final;

  /**
   * @brief Finalize transformation in this module
   *
   * This method will not return until all transformation result is written into next module
   */
  void
  doEnd() final;

  /**
   * @brief Process before transformation.
   *
   * @pre Output buffer is empty.
   *
   * This method is invoked before every convert(...) invocation.
   *
   * This implementation does nothing.  A subclass can override this method to perform
   * specific pre-transformation procedure, e.g., read partial transformation results into
   * output buffer.
   */
  virtual void
  preTransform();

  /**
   * @brief Convert input @p data.
   *
   * @return The number of input bytes that have been accepted by the converter.
   */
  virtual size_t
  convert(span<const uint8_t> data) = 0;

  /**
   * @brief Finalize the transformation.
   *
   * This implementation only flushes content in output buffer into next module.
   * A subclass can override this method to perform specific finalization procedure, i.e.,
   * finalize the transformation and flush the result into next module.
   */
  virtual void
  finalize();

private:
  unique_ptr<OBuffer> m_oBuffer;
  size_t m_outputOffset = 0;
};

/**
 * @brief Abstraction of the transformation sink module.
 *
 * This module does not have a next module and can only accept input data.
 */
class Sink : public Downstream
{
};

/**
 * @brief Abstraction of the transformation source module.
 *
 * This module can only accept input data from the constructor.
 */
class Source : public Upstream
{
public:
  /**
   * @brief Connect to an intermediate transformation module.
   */
  Source&
  operator>>(unique_ptr<Transform> transform);

  /**
   * @brief Connect to the last transformation module.
   *
   * This method will trigger the source to pump data into the transformation pipeline.
   */
  void
  operator>>(unique_ptr<Sink> sink);

protected:
  Source() = default;

  /**
   * @brief Pump all data into next transformation module.
   */
  void
  pump();

  /**
   * @brief Get the source module index (should always be 0).
   */
  size_t
  getIndex() const
  {
    return 0;
  }

private:
  virtual void
  doPump() = 0;

private:
  size_t m_nModules = 1; // count of modules in the chain starting from (and including) this Source
};

} // namespace transform
} // namespace security
} // namespace ndn

#endif // NDN_CXX_SECURITY_TRANSFORM_BASE_HPP
