/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/*
 * Copyright (c) 2011 University of California, Los Angeles
 *
 * 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: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
 *
 */

#include "ndn-net-device-face.hpp"
#include "ndn-l3-protocol.hpp"

#include "ns3/net-device.h"
#include "ns3/log.h"
#include "ns3/packet.h"
#include "ns3/node.h"
#include "ns3/pointer.h"

// #include "ns3/address.h"
#include "ns3/point-to-point-net-device.h"
#include "ns3/channel.h"
#include "ns3/ndn-name.hpp"

NS_LOG_COMPONENT_DEFINE("ndn.NetDeviceFace");

namespace ns3 {
namespace ndn {

NS_OBJECT_ENSURE_REGISTERED(NetDeviceFace);

TypeId
NetDeviceFace::GetTypeId()
{
  static TypeId tid = TypeId("ns3::ndn::NetDeviceFace").SetParent<Face>().SetGroupName("Ndn");
  return tid;
}

/**
 * By default, Ndn face are created in the "down" state.  Before
 * becoming useable, the user must invoke SetUp on the face
 */
NetDeviceFace::NetDeviceFace(Ptr<Node> node, const Ptr<NetDevice>& netDevice)
  : Face(node)
  , m_netDevice(netDevice)
{
  NS_LOG_FUNCTION(this << netDevice);

  SetMetric(1); // default metric

  NS_ASSERT_MSG(m_netDevice != 0, "NetDeviceFace needs to be assigned a valid NetDevice");
}

NetDeviceFace::~NetDeviceFace()
{
  NS_LOG_FUNCTION_NOARGS();
}

NetDeviceFace& NetDeviceFace::operator= (const NetDeviceFace &)
{
  return *this;
}

Ptr<NetDevice>
NetDeviceFace::GetNetDevice() const
{
  return m_netDevice;
}

void
NetDeviceFace::RegisterProtocolHandlers(const InterestHandler& interestHandler,
                                        const DataHandler& dataHandler)
{
  NS_LOG_FUNCTION(this);

  Face::RegisterProtocolHandlers(interestHandler, dataHandler);

  m_node->RegisterProtocolHandler(MakeCallback(&NetDeviceFace::ReceiveFromNetDevice, this),
                                  L3Protocol::ETHERNET_FRAME_TYPE, m_netDevice,
                                  true /*promiscuous mode*/);
}

void
NetDeviceFace::UnRegisterProtocolHandlers()
{
  m_node->UnregisterProtocolHandler(MakeCallback(&NetDeviceFace::ReceiveFromNetDevice, this));
  Face::UnRegisterProtocolHandlers();
}

bool
NetDeviceFace::Send(Ptr<Packet> packet)
{
  if (!Face::Send(packet)) {
    return false;
  }

  NS_LOG_FUNCTION(this << packet);

  NS_ASSERT_MSG(packet->GetSize() <= m_netDevice->GetMtu(),
                "Packet size " << packet->GetSize() << " exceeds device MTU "
                               << m_netDevice->GetMtu() << " for Ndn; fragmentation not supported");

  bool ok = m_netDevice->Send(packet, m_netDevice->GetBroadcast(), L3Protocol::ETHERNET_FRAME_TYPE);
  return ok;
}

// callback
void
NetDeviceFace::ReceiveFromNetDevice(Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol,
                                    const Address& from, const Address& to,
                                    NetDevice::PacketType packetType)
{
  NS_LOG_FUNCTION(device << p << protocol << from << to << packetType);
  Receive(p);
}

std::ostream&
NetDeviceFace::Print(std::ostream& os) const
{
#ifdef NS3_LOG_ENABLE
  os << "dev[" << GetNode()->GetId() << "]=net(" << GetId();

  if (DynamicCast<PointToPointNetDevice>(m_netDevice)) {
    // extra debugging information which available ONLY for PointToPointNetDevice's
    os << ",";
    os << DynamicCast<PointToPointNetDevice>(m_netDevice)
            ->GetChannel()
            ->GetDevice(0)
            ->GetNode()
            ->GetId();
    os << "-";
    os << DynamicCast<PointToPointNetDevice>(m_netDevice)
            ->GetChannel()
            ->GetDevice(1)
            ->GetNode()
            ->GetId();
  }
  os << ")";
#else
  os << "dev=net(" << GetId() << ")";
#endif
  return os;
}

} // namespace ndnsim
} // namespace ns3
