/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/**
 * Copyright (c) 2013-2014,  Regents of the University of California.
 * All rights reserved.
 *
 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
 *
 * This file licensed under New BSD License.  See COPYING for detailed information about
 * ndn-cxx library copyright, permissions, and redistribution restrictions.
 */

#ifndef NDN_FORWARDING_FLAGS_HPP
#define NDN_FORWARDING_FLAGS_HPP

#include "../encoding/block.hpp"
#include "../encoding/tlv-ndnd.hpp"

namespace ndn {
namespace ndnd {

/**
 * A ForwardingFlags object holds the flags which specify how the forwarding daemon should forward an interest for
 * a registered prefix.  We use a separate ForwardingFlags object to retain future compatibility if the daemon forwarding
 * bits are changed, amended or deprecated.
 */
class ForwardingFlags
{
public:
  /**
   * Create a new ForwardingFlags with "active" and "childInherit" set and all other flags cleared.
   */
  ForwardingFlags()
    : active_(true)
    , childInherit_(true)
    , advertise_(false)
    , last_(false)
    , capture_(false)
    , local_(false)
    , tap_(false)
    , captureOk_(false)
  {
  }

  /**
   * @brief Create from wire encoding
   */
  explicit
  ForwardingFlags(const Block& wire)
  {
    wireDecode(wire);
  }

  /**
   * Get the value of the "active" flag.
   * @return true if the flag is set, false if it is cleared.
   */
  bool getActive() const { return active_; }

  /**
   * Get the value of the "childInherit" flag.
   * @return true if the flag is set, false if it is cleared.
   */
  bool getChildInherit() const { return childInherit_; }

  /**
   * Get the value of the "advertise" flag.
   * @return true if the flag is set, false if it is cleared.
   */
  bool getAdvertise() const { return advertise_; }

  /**
   * Get the value of the "last" flag.
   * @return true if the flag is set, false if it is cleared.
   */
  bool getLast() const { return last_; }

  /**
   * Get the value of the "capture" flag.
   * @return true if the flag is set, false if it is cleared.
   */
  bool getCapture() const { return capture_; }

  /**
   * Get the value of the "local" flag.
   * @return true if the flag is set, false if it is cleared.
   */
  bool getLocal() const { return local_; }

  /**
   * Get the value of the "tap" flag.
   * @return true if the flag is set, false if it is cleared.
   */
  bool getTap() const { return tap_; }

  /**
   * Get the value of the "captureOk" flag.
   * @return true if the flag is set, false if it is cleared.
   */
  bool getCaptureOk() const { return captureOk_; }

  /**
   * Set the value of the "active" flag
   * @param active true to set the flag, false to clear it.
   */
  void setActive(bool active) { this->active_ = active; wire_.reset(); }

  /**
   * Set the value of the "childInherit" flag
   * @param childInherit true to set the flag, false to clear it.
   */
  void setChildInherit(bool childInherit) { this->childInherit_ = childInherit; wire_.reset(); }

  /**
   * Set the value of the "advertise" flag
   * @param advertise true to set the flag, false to clear it.
   */
  void setAdvertise(bool advertise) { this->advertise_ = advertise; wire_.reset(); }

  /**
   * Set the value of the "last" flag
   * @param last true to set the flag, false to clear it.
   */
  void setLast(bool last) { this->last_ = last; wire_.reset(); }

  /**
   * Set the value of the "capture" flag
   * @param capture true to set the flag, false to clear it.
   */
  void setCapture(bool capture) { this->capture_ = capture; wire_.reset(); }

  /**
   * Set the value of the "local" flag
   * @param local true to set the flag, false to clear it.
   */
  void setLocal(bool local) { this->local_ = local; wire_.reset(); }

  /**
   * Set the value of the "tap" flag
   * @param tap true to set the flag, false to clear it.
   */
  void setTap(bool tap) { this->tap_ = tap; wire_.reset(); }

  /**
   * Set the value of the "captureOk" flag
   * @param captureOk true to set the flag, false to clear it.
   */
  void setCaptureOk(bool captureOk) { this->captureOk_ = captureOk; wire_.reset(); }

  inline const Block&
  wireEncode() const;

  inline void
  wireDecode(const Block& block);

private:
  bool active_;
  bool childInherit_;
  bool advertise_;
  bool last_;
  bool capture_;
  bool local_;
  bool tap_;
  bool captureOk_;

  mutable Block wire_;
};

inline const Block&
ForwardingFlags::wireEncode() const
{
  if (wire_.hasWire())
    return wire_;

  uint32_t result = 0;
  if (active_)
    result |= tlv::ndnd::FORW_ACTIVE;
  if (childInherit_)
    result |= tlv::ndnd::FORW_CHILD_INHERIT;
  if (advertise_)
    result |= tlv::ndnd::FORW_ADVERTISE;
  if (last_)
    result |= tlv::ndnd::FORW_LAST;
  if (capture_)
    result |= tlv::ndnd::FORW_CAPTURE;
  if (local_)
    result |= tlv::ndnd::FORW_LOCAL;
  if (tap_)
    result |= tlv::ndnd::FORW_TAP;
  if (captureOk_)
    result |= tlv::ndnd::FORW_CAPTURE_OK;

  wire_ = nonNegativeIntegerBlock(tlv::ndnd::ForwardingFlags, result);

  return wire_;
}

inline void
ForwardingFlags::wireDecode(const Block& wire)
{
  wire_ = wire;

  uint32_t flags = readNonNegativeInteger(wire_);

  active_       = (flags & tlv::ndnd::FORW_ACTIVE)        ? true : false;
  childInherit_ = (flags & tlv::ndnd::FORW_CHILD_INHERIT) ? true : false;
  advertise_    = (flags & tlv::ndnd::FORW_ADVERTISE)     ? true : false;
  last_         = (flags & tlv::ndnd::FORW_LAST)          ? true : false;
  capture_      = (flags & tlv::ndnd::FORW_CAPTURE)       ? true : false;
  local_        = (flags & tlv::ndnd::FORW_LOCAL)         ? true : false;
  tap_          = (flags & tlv::ndnd::FORW_TAP)           ? true : false;
  captureOk_    = (flags & tlv::ndnd::FORW_CAPTURE_OK)    ? true : false;
}

inline std::ostream&
operator << (std::ostream& os, const ForwardingFlags& flags)
{
  if (flags.getActive())
    os << "ACTIVE ";
  if (flags.getChildInherit())
    os << "CHILE_INHERIT ";
  if (flags.getAdvertise())
    os << "ADVERTISE ";
  if (flags.getLast())
    os << "LAST ";
  if (flags.getCapture())
    os << "CAPTURE ";
  if (flags.getLocal())
    os << "LOCAL ";
  if (flags.getTap())
    os << "TAP ";
  if (flags.getCaptureOk())
    os << "CAPTURE_OK ";

  return os;
}

} // namespace ndnd
} // namespace ndn

#endif
