/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
//
// Copyright (c) 2006 Georgia Tech Research Corporation
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation;
//
// This program 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 this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// Author: 
//

#ifndef CCNX_L3_PROTOCOL_H
#define CCNX_L3_PROTOCOL_H

#include <list>
#include <vector>
#include <stdint.h>
#include "ns3/ptr.h"
#include "ns3/net-device.h"
#include "ns3/traced-callback.h"

#include "ccnx.h"

namespace ns3 {

class Packet;
class NetDevice;
class Node;
class CcnxFace;
class CcnxRoute;
class CcnxForwardingStrategy;
class Header;
class CcnxInterestHeader;
class CcnxContentObjectHeader;
  
/**
 * \brief Implement the Ccnx layer.
 * 
 * This is the actual implementation of IP.  It contains APIs to send and
 * receive packets at the IP layer, as well as APIs for IP routing.
 *
 * This class contains two distinct groups of trace sources.  The
 * trace sources 'Rx' and 'Tx' are called, respectively, immediately
 * after receiving from the NetDevice and immediately before sending
 * to a NetDevice for transmitting a packet.  These are low level
 * trace sources that include the CcnxHeader already serialized into
 * the packet.  In contrast, the Drop, SendOutgoing, UnicastForward,
 * and LocalDeliver trace sources are slightly higher-level and pass
 * around the CcnxHeader as an explicit parameter and not as part of
 * the packet.
 */
class CcnxL3Protocol : public Ccnx
{
public:
  static TypeId GetTypeId (void);
  static const uint16_t PROT_NUMBER;

  CcnxL3Protocol();
  virtual ~CcnxL3Protocol ();

  /**
   * \enum DropReason
   * \brief Reason why a packet has been dropped.
   */
  enum DropReason 
  {
    /** \todo  Fill reasons from QualNet code */
    DROP_DUPLICATE_INTEREST=1,  /**< Duplicate Interest */
    DROP_CONGESTION, /**< Congestion detected */
    DROP_NO_ROUTE,   /**< No route to host */
    DROP_INTERFACE_DOWN,   /**< Interface is down so can not send packet */
    DROP_ROUTE_ERROR,   /**< Route error */
  };

  void SetNode (Ptr<Node> node);

  // functions defined in base class Ccnx
  
  void SetForwardingStrategy (Ptr<CcnxForwardingStrategy> forwardingStrategy);
  Ptr<CcnxForwardingStrategy> GetForwardingStrategy (void) const;

  /**
   * Lower layer calls this method after calling L3Demux::Lookup
   *
   * \param device network device
   * \param p the packet
   * \param protocol lower layer protocol value
   * \param from lower layer address of the correspondant
   * \param to lower layer address of the destination
   * \param packetType type of the packet (broadcast/multicast/unicast/otherhost)
   */
  void ReceiveFromLower (Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol,
                 const Address &from,
                 const Address &to,
                 NetDevice::PacketType packetType);

  /**
   * Actual processing of incoming CCNx packets. Also processing packets coming from local apps
   * 
   * Processing Interest packets
   */
  virtual void
  ReceiveAndProcess (Ptr<CcnxFace> face, Ptr<CcnxInterestHeader> header, Ptr<Packet> p);

  
  /**
   * Actual processing of incoming CCNx packets. Also processing packets coming from local apps
   * 
   * Processing ContentObject packets
   */
  virtual void
  ReceiveAndProcess (Ptr<CcnxFace> face, Ptr<CcnxContentObjectHeader> header, Ptr<Packet> p);
  
  /**
   * \param packet packet to send
   * \param route route entry
   *
   * Higher-level layers call this method to send a packet
   * down the stack to the MAC and PHY layers.
   */
  virtual void Send (Ptr<Packet> packet, Ptr<CcnxRoute> route);

  virtual uint32_t AddFace (Ptr<CcnxFace> face);
  virtual uint32_t GetNFaces (void) const;
  virtual Ptr<CcnxFace> GetFace (uint32_t face) const;

  virtual void SetMetric (uint32_t i, uint16_t metric);
  virtual uint16_t GetMetric (uint32_t i) const;
  virtual uint16_t GetMtu (uint32_t i) const;
  virtual bool IsUp (uint32_t i) const;
  virtual void SetUp (uint32_t i);
  virtual void SetDown (uint32_t i);

protected:
  virtual void DoDispose (void);
  /**
   * This function will notify other components connected to the node that a new stack member is now connected
   * This will be used to notify Layer 3 protocol of layer 4 protocol stack to connect them together.
   */
  virtual void NotifyNewAggregate ();

private:
  // friend class CcnxL3ProtocolTestCase;
  CcnxL3Protocol(const CcnxL3Protocol &);
  CcnxL3Protocol &operator = (const CcnxL3Protocol &);

  /**
   * Helper function to get CcnxFace from NetDevice
   */
  Ptr<CcnxFace> GetFaceForDevice (Ptr<const NetDevice> device) const;
  
  void RouteInputError (Ptr<Packet> p);
                        //, Socket::SocketErrno sockErrno);

  /**
   * false function. should never be called. Just to trick C++ to compile
   */
  virtual void
  ReceiveAndProcess (Ptr<CcnxFace> face, Ptr<Header> header, Ptr<Packet> p);

private:
  typedef std::vector<Ptr<CcnxFace> > CcnxFaceList;
  CcnxFaceList m_faces;

  Ptr<Node> m_node;
  Ptr<CcnxForwardingStrategy> m_forwardingStrategy;

  TracedCallback<Ptr<const Packet>, Ptr<const CcnxFace> > m_sendOutgoingTrace;
  TracedCallback<Ptr<const Packet>, Ptr<const CcnxFace> > m_unicastForwardTrace;
  TracedCallback<Ptr<const Packet>, Ptr<const CcnxFace> > m_localDeliverTrace;

  // The following two traces pass a packet with an IP header
  TracedCallback<Ptr<const Packet>, Ptr<Ccnx>, Ptr<const CcnxFace> > m_txTrace;
  TracedCallback<Ptr<const Packet>, Ptr<Ccnx>, Ptr<const CcnxFace> > m_rxTrace;
  // <ip-header, payload, reason, ifindex> (ifindex not valid if reason is DROP_NO_ROUTE)
  TracedCallback<Ptr<const Packet>, DropReason, Ptr<const Ccnx>, Ptr<const CcnxFace> > m_dropTrace;
};
  
} // Namespace ns3

#endif /* CCNX_L3_PROTOCOL_H */
