//
//  ndn_stupidinterestgenerator.cpp
//  Abstraction
//
//  Created by Ilya Moiseenko on 05.08.11.
//  Copyright 2011 UCLA. All rights reserved.
//

#include "stupid-interest-generator.h"

#include "ns3/socket.h"
#include "ns3/socket-factory.h"
#include "ns3/simulator.h"

#include "model/interest-packet.h"
#include "model/name-builder.h"

NS_LOG_COMPONENT_DEFINE ("StupidInterestGenerator");

namespace ns3
{
//namespace NDNabstraction
//{
    using namespace NDNabstraction;
    
    NS_OBJECT_ENSURE_REGISTERED (StupidInterestGenerator);
    
    TypeId
    StupidInterestGenerator::GetTypeId (void)
    {
        static TypeId tid = TypeId ("ns3::StupidInterestGenerator")
        .SetParent<Application> ()
        .AddConstructor<StupidInterestGenerator> ()
        .AddAttribute ("Remote", "The address of the destination",
                       AddressValue (),
                       MakeAddressAccessor (&StupidInterestGenerator::m_peer),
                       MakeAddressChecker ())
        .AddAttribute ("OffTime", "Time interval between packets",
                       TimeValue (Seconds (0.1)),
                       MakeTimeAccessor (&StupidInterestGenerator::m_offTime),
                       MakeTimeChecker ())
        .AddAttribute ("Protocol", "The type of protocol to use.",
                       TypeIdValue (UdpSocketFactory::GetTypeId ()),
                       MakeTypeIdAccessor (&StupidInterestGenerator::m_tid),
                       MakeTypeIdChecker ())
        ;
        return tid;
    }

    StupidInterestGenerator::StupidInterestGenerator ()
    {
        NS_LOG_FUNCTION_NOARGS ();
        m_socket = 0;
        //m_connected = false;
        //m_residualBits = 0;
        //m_lastStartTime = Seconds (0);
        //m_totBytes = 0;
    }
    
    StupidInterestGenerator::~StupidInterestGenerator()
    {
        NS_LOG_FUNCTION_NOARGS ();
    }
    
    void
    StupidInterestGenerator::DoDispose (void)
    {
        NS_LOG_FUNCTION_NOARGS ();
        
        m_socket = 0;
        // chain up
        Application::DoDispose ();
    }
    
    // Application Methods
    void StupidInterestGenerator::StartApplication () // Called at time specified by Start
    {
        NS_LOG_FUNCTION_NOARGS ();
        
        // Create the socket if not already
        if (!m_socket)
        {
            m_socket = Socket::CreateSocket (GetNode (), m_tid);
            m_socket->Bind ();
            m_socket->Connect (m_peer);
            m_socket->SetAllowBroadcast (true);
            m_socket->ShutdownRecv ();
        }
        // Insure no pending event
        CancelEvents ();
        // If we are not yet connected, there is nothing to do here
        // The ConnectionComplete upcall will start timers at that time
        //if (!m_connected) return;
        ScheduleStartEvent ();
    }
    
    void StupidInterestGenerator::StopApplication () // Called at time specified by Stop
    {
        NS_LOG_FUNCTION_NOARGS ();
        
        CancelEvents ();
        if(m_socket != 0)
        {
            m_socket->Close ();
        }
        else
        {
            NS_LOG_WARN ("OnOffApplication found null socket to close in StopApplication");
        }
    }
    
    void StupidInterestGenerator::CancelEvents ()
    {
        NS_LOG_FUNCTION_NOARGS ();
        
        Simulator::Cancel (m_sendEvent);
        Simulator::Cancel (m_startStopEvent);
    }

    void StupidInterestGenerator::ScheduleStartEvent ()
    {  // Schedules the event to start sending data (switch to the "On" state)
        NS_LOG_FUNCTION_NOARGS ();
        
        Time offInterval = Seconds (m_offTime);
        NS_LOG_LOGIC ("start at " << offInterval);
        m_startStopEvent = Simulator::Schedule (offInterval, &StupidInterestGenerator::StartSending, this);
    }
    
    // Event handlers
    void StupidInterestGenerator::StartSending ()
    {
        NS_LOG_FUNCTION_NOARGS ();
        //m_lastStartTime = Simulator::Now ();
        ScheduleNextTx ();  // Schedule the send packet event
        //ScheduleStopEvent ();
    }
    
    void StupidInterestGenerator::StopSending ()
    {
        NS_LOG_FUNCTION_NOARGS ();
        CancelEvents ();
        
        ScheduleStartEvent ();
    }
    
    // Private helpers
    void StupidInterestGenerator::ScheduleNextTx ()
    {
        NS_LOG_FUNCTION_NOARGS ();
        

        Time nextTime = Seconds(0.); //send now
        m_sendEvent = Simulator::Schedule (nextTime,
                                               &StupidInterestGenerator::SendPacket, this);
    }

        
    void StupidInterestGenerator::SendPacket ()
    {
        // NS_LOG_FUNCTION_NOARGS ();
        // NS_LOG_LOGIC ("sending packet at " << Simulator::Now ());
        // NS_ASSERT (m_sendEvent.IsExpired ());
        
        // NameBuilder name;
		// name("prefix1")("prefix2")("filename");
		
        // const ccn_charbuf *output = name.GetName();
        // Ptr<InterestPacket> packet = Create<InterestPacket>(name,(uint32_t)output->length);
        // packet->AddTimeout(4000);
        // UniformVariable var;
        // packet->AddNonce(var.GetInteger(1,10000));
        // m_socket->Send(packet);
        
        // ScheduleStartEvent();
    }

//}
}
