/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2013-2016 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 "../../common.hpp"
#include <vector>

namespace ndn {
namespace security {
namespace transform {

/**
 * @file transform-base.hpp
 *
 * 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
{
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 has been written into this module
   * @throws Error if this module is closed or transformation error happens.
   */
  size_t
  write(const uint8_t* buf, size_t size);

  /**
   * @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();

private:
  /**
   * @brief Internal implementation of write method
   */
  virtual size_t
  doWrite(const uint8_t* buf, size_t size) = 0;

  /**
   * @brief Internal implementation of end method
   */
  virtual void
  doEnd() = 0;

private:
  bool m_isEnd;
  size_t m_index;
};

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

protected:
  Upstream();

protected:
  /**
   * @brief connect to 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,
                  noncopyable
{
protected:
  typedef std::vector<uint8_t> OBuffer;

  Transform();

  /**
   * @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:
  /**
   * @brief Abstraction of data processing in an intermediate module
   */
  virtual size_t
  doWrite(const uint8_t* data, size_t dataLen) final;

  /**
   * @brief Finalize transformation in this module
   *
   * This method will not return until all transformation result is written into next module
   */
  virtual 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(const uint8_t* data, size_t dataLen) = 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;
};

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

/**
 * @brief Abstraction of the transformation source module
 *
 * This module can only accept input data from constructor
 */
class Source : public Upstream,
               noncopyable
{
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();

  /**
   * @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:
  /**
   * @brief Internal implementation of pump().
   */
  virtual void
  doPump() = 0;

private:
  size_t m_nModules; // count of modules in the chain starting from this Source
};

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

#endif // NDN_CXX_SECURITY_TRANSFORM_BASE_HPP
