/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
//
//  stupid-interest-sink.cpp
//  Abstraction
//
//  Created by Ilya Moiseenko on 10.08.11.
//  Copyright 2011 UCLA. All rights reserved.
//

#include "stupid-interest-sink.h"

#include "ns3/address.h"
#include "ns3/address-utils.h"
#include "ns3/log.h"
#include "ns3/inet-socket-address.h"
#include "ns3/node.h"
#include "ns3/socket.h"
#include "ns3/udp-socket.h"
#include "ns3/simulator.h"
#include "ns3/socket-factory.h"
#include "ns3/packet.h"
#include "ns3/trace-source-accessor.h"
#include "ns3/udp-socket-factory.h"

using namespace std;

namespace ns3 {
    
    NS_LOG_COMPONENT_DEFINE ("StupidInterestSink");
    NS_OBJECT_ENSURE_REGISTERED (StupidInterestSink);
    
    TypeId 
    StupidInterestSink::GetTypeId (void)
    {
        static TypeId tid = TypeId ("ns3::StupidInterestSink")
        .SetParent<Application> ()
        .AddConstructor<StupidInterestSink> ()
        .AddAttribute ("Local", "The Address on which to Bind the rx socket.",
                       AddressValue (),
                       MakeAddressAccessor (&StupidInterestSink::m_local),
                       MakeAddressChecker ())
        .AddAttribute ("Protocol", "The type id of the protocol to use for the rx socket.",
                       TypeIdValue (UdpSocketFactory::GetTypeId ()),
                       MakeTypeIdAccessor (&StupidInterestSink::m_tid),
                       MakeTypeIdChecker ())
        .AddTraceSource ("Rx", "A packet has been received",
                         MakeTraceSourceAccessor (&StupidInterestSink::m_rxTrace))
        ;
        return tid;
    }
    
    StupidInterestSink::StupidInterestSink ()
    {
        NS_LOG_FUNCTION (this);
        m_socket = 0;
        m_totalRx = 0;
    }
    
    StupidInterestSink::~StupidInterestSink()
    {
        NS_LOG_FUNCTION (this);
    }
    
    uint32_t StupidInterestSink::GetTotalRx () const
    {
        return m_totalRx;
    }
    
    Ptr<Socket>
    StupidInterestSink::GetListeningSocket (void) const
    {
        NS_LOG_FUNCTION (this);
        return m_socket;
    }
    
    std::list<Ptr<Socket> >
    StupidInterestSink::GetAcceptedSockets (void) const
    {
        NS_LOG_FUNCTION (this);
        return m_socketList;
    }
    
    void StupidInterestSink::DoDispose (void)
    {
        NS_LOG_FUNCTION (this);
        m_socket = 0;
        m_socketList.clear ();
        
        // chain up
        Application::DoDispose ();
    }
    
    
    // Application Methods
    void StupidInterestSink::StartApplication ()    // Called at time specified by Start
    {
        NS_LOG_FUNCTION (this);
        // Create the socket if not already
        if (!m_socket)
        {
            m_socket = Socket::CreateSocket (GetNode (), m_tid);
            m_socket->Bind (m_local);
            m_socket->Listen ();
            m_socket->ShutdownSend ();
            if (addressUtils::IsMulticast (m_local))
            {
                Ptr<UdpSocket> udpSocket = DynamicCast<UdpSocket> (m_socket);
                if (udpSocket)
                {
                    // equivalent to setsockopt (MCAST_JOIN_GROUP)
                    udpSocket->MulticastJoinGroup (0, m_local);
                }
                else
                {
                    NS_FATAL_ERROR ("Error: joining multicast on a non-UDP socket");
                }
            }
        }
        
        m_socket->SetRecvCallback (MakeCallback (&StupidInterestSink::HandleRead, this));
        m_socket->SetAcceptCallback (
                                     MakeNullCallback<bool, Ptr<Socket>, const Address &> (),
                                     MakeCallback (&StupidInterestSink::HandleAccept, this));
        m_socket->SetCloseCallbacks (
                                     MakeCallback (&StupidInterestSink::HandlePeerClose, this),
                                     MakeCallback (&StupidInterestSink::HandlePeerError, this));
    }
    
    void StupidInterestSink::StopApplication ()     // Called at time specified by Stop
    {
        NS_LOG_FUNCTION (this);
        while(!m_socketList.empty ()) //these are accepted sockets, close them
        {
            Ptr<Socket> acceptedSocket = m_socketList.front ();
            m_socketList.pop_front ();
            acceptedSocket->Close ();
        }
        if (m_socket) 
        {
            m_socket->Close ();
            m_socket->SetRecvCallback (MakeNullCallback<void, Ptr<Socket> > ());
        }
    }
    
    void StupidInterestSink::HandleRead (Ptr<Socket> socket)
    {
        NS_LOG_FUNCTION (this << socket);
        Ptr<Packet> packet;
        Address from;
        while (packet = socket->RecvFrom (from))
        {
            if (packet->GetSize () == 0)
            { //EOF
                break;
            }
            if (InetSocketAddress::IsMatchingType (from))
            {
                m_totalRx += packet->GetSize ();
                InetSocketAddress address = InetSocketAddress::ConvertFrom (from);
                NS_LOG_INFO ("Received " << packet->GetSize () << " bytes from " <<
                             address.GetIpv4 () << " [" << address << "]"
                             << " total Rx " << m_totalRx);
                //cast address to void , to suppress 'address' set but not used 
                //compiler warning in optimized builds
                (void) address;
            }
            m_rxTrace (packet, from);
        }
    }
    
    void StupidInterestSink::HandlePeerClose (Ptr<Socket> socket)
    {
        NS_LOG_INFO ("PktSink, peerClose");
    }
    
    void StupidInterestSink::HandlePeerError (Ptr<Socket> socket)
    {
        NS_LOG_INFO ("PktSink, peerError");
    }
    
    
    void StupidInterestSink::HandleAccept (Ptr<Socket> s, const Address& from)
    {
        NS_LOG_FUNCTION (this << s << from);
        s->SetRecvCallback (MakeCallback (&StupidInterestSink::HandleRead, this));
        m_socketList.push_back (s);
    }
    
} // Namespace ns3
