/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2013-2015 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_LP_PACKET_HPP
#define NDN_CXX_LP_PACKET_HPP

#include "fields.hpp"

namespace ndn {
namespace lp {

class Packet
{
public:
  class Error : public ndn::tlv::Error
  {
  public:
    explicit
    Error(const std::string& what)
      : ndn::tlv::Error(what)
    {
    }
  };

  Packet();

  explicit
  Packet(const Block& wire);

  /**
   * \brief append packet to encoder
   */
  template<encoding::Tag TAG>
  size_t
  wireEncode(EncodingImpl<TAG>& encoder) const;

  /**
   * \brief encode packet into wire format
   */
  const Block&
  wireEncode() const;

  /**
   * \brief decode packet from wire format
   */
  void
  wireDecode(const Block& wire);

public: // field access
  /**
   * \return true if FIELD occurs one or more times
   * \detail This is equivalent to count()>0
   */
  template<typename FIELD>
  bool
  has() const
  {
    return count<FIELD>() > 0;
  }

  /**
   * \return number of occurrences of FIELD
   */
  template<typename FIELD>
  size_t
  count() const
  {
    m_wire.parse();

    return std::count_if(m_wire.elements_begin(), m_wire.elements_end(),
                         [] (const Block& block) {
                           return block.type() == FIELD::TlvType::value; });
  }

  /**
   * \return value of index-th occurrence of FIELD
   * \throw std::out_of_range if index>=count()
   */
  template<typename FIELD>
  typename FIELD::ValueType
  get(size_t index = 0) const
  {
    m_wire.parse();

    size_t count = 0;
    for (const Block& element : m_wire.elements()) {
      if (element.type() != FIELD::TlvType::value) {
        continue;
      }
      if (count++ == index) {
        return FIELD::decode(element);
      }
    }

    throw std::out_of_range("Index out of range");
  }

  /**
   * \return values of all occurrences of FIELD
   */
  template<typename FIELD>
  std::vector<typename FIELD::ValueType>
  list() const
  {
    std::vector<typename FIELD::ValueType> output;

    m_wire.parse();

    for (const Block& element : m_wire.elements()) {
      if (element.type() != FIELD::TlvType::value) {
        continue;
      }
      output.push_back(FIELD::decode(element));
    }

    return output;
  }

  /**
   * \brief remove all occurrences of FIELD, and add a FIELD with value
   * \detail This equivalent to clear() followed by add(value)
   */
  template<typename FIELD>
  Packet&
  set(const typename FIELD::ValueType& value)
  {
    clear<FIELD>();
    return add<FIELD>(value);
  }

  /**
   * \brief add a FIELD with value
   * \throw std::length_error if field already exists and is not repeatable
   */
  template<typename FIELD>
  Packet&
  add(const typename FIELD::ValueType& value)
  {
    if (!FIELD::IsRepeatable::value && has<FIELD>()) {
      throw std::length_error("Field cannot be repeated");
    }

    EncodingEstimator estimator;
    size_t estimatedSize = FIELD::encode(estimator, value);
    EncodingBuffer buffer(estimatedSize, 0);
    FIELD::encode(buffer, value);
    Block block = buffer.block();

    Block::element_const_iterator pos = std::lower_bound(m_wire.elements_begin(),
                                                         m_wire.elements_end(),
                                                         FIELD::TlvType::value,
                                                         comparePos);
    m_wire.insert(pos, block);

    return *this;
  }

  /**
   * \brief remove the index-th occurrence of FIELD
   * \throw std::out_of_range if index>=count()
   */
  template<typename FIELD>
  Packet&
  remove(size_t index = 0)
  {
    m_wire.parse();

    size_t count = 0;
    for (Block::element_const_iterator it = m_wire.elements_begin(); it != m_wire.elements_end();
         ++it) {
      if (it->type() == FIELD::TlvType::value) {
        if (count == index) {
          m_wire.erase(it);
          return *this;
        }
        count++;
      }
    }

    throw std::out_of_range("Index out of range");
  }

  /**
   * \brief remove all occurrences of FIELD
   */
  template<typename FIELD>
  Packet&
  clear()
  {
    m_wire.parse();
    m_wire.remove(FIELD::TlvType::value);
    return *this;
  }

private:
  static bool
  comparePos(const Block& first, const uint64_t second);

private:
  mutable Block m_wire;
};

} // namespace lp
} // namespace ndn

#endif // NDN_CXX_LP_PACKET_HPP