/* -*-  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: Ilya Moiseenko <iliamo@cs.ucla.edu>
 *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
 */

#include "ndn-producer.h"
#include "ns3/log.h"
#include "ns3/ndn-interest-header.h"
#include "ns3/ndn-content-object-header.h"
#include "ns3/string.h"
#include "ns3/uinteger.h"
#include "ns3/packet.h"
#include "ns3/simulator.h"

#include "ns3/ndn-app-face.h"
#include "ns3/ndn-fib.h"
// #include "../model/ndn-fib-impl.h"

#include <boost/ref.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
namespace ll = boost::lambda;

NS_LOG_COMPONENT_DEFINE ("NdnProducer");

namespace ns3
{    

NS_OBJECT_ENSURE_REGISTERED (NdnProducer);
    
TypeId
NdnProducer::GetTypeId (void)
{
  static TypeId tid = TypeId ("ns3::NdnProducer")
    .SetGroupName ("Ndn")
    .SetParent<NdnApp> ()
    .AddConstructor<NdnProducer> ()
    .AddAttribute ("Prefix","Prefix, for which producer has the data",
                   StringValue ("/"),
                   MakeNdnNameComponentsAccessor (&NdnProducer::m_prefix),
                   MakeNdnNameComponentsChecker ())
    .AddAttribute ("PayloadSize", "Virtual payload size for Content packets",
                   UintegerValue (1024),
                   MakeUintegerAccessor(&NdnProducer::m_virtualPayloadSize),
                   MakeUintegerChecker<uint32_t>())

    // optional attributes
    .AddAttribute ("SignatureBits", "SignatureBits field",
                   UintegerValue (0),
                   MakeUintegerAccessor(&NdnProducer::m_signatureBits),
                   MakeUintegerChecker<uint32_t> ())
    ;
        
  return tid;
}
    
NdnProducer::NdnProducer ()
{
  // NS_LOG_FUNCTION_NOARGS ();
}

// inherited from Application base class.
void
NdnProducer::StartApplication ()
{
  NS_LOG_FUNCTION_NOARGS ();
  NS_ASSERT (GetNode ()->GetObject<NdnFib> () != 0);

  NdnApp::StartApplication ();

  NS_LOG_DEBUG ("NodeID: " << GetNode ()->GetId ());
  
  Ptr<NdnFib> fib = GetNode ()->GetObject<NdnFib> ();
  
  Ptr<NdnFibEntry> fibEntry = fib->Add (m_prefix, m_face, 0);

  fibEntry->UpdateStatus (m_face, NdnFibFaceMetric::NDN_FIB_GREEN);
  
  // // make face green, so it will be used primarily
  // StaticCast<NdnFibImpl> (fib)->modify (fibEntry,
  //                                        ll::bind (&NdnFibEntry::UpdateStatus,
  //                                                  ll::_1, m_face, NdnFibFaceMetric::NDN_FIB_GREEN));
}

void
NdnProducer::StopApplication ()
{
  NS_LOG_FUNCTION_NOARGS ();
  NS_ASSERT (GetNode ()->GetObject<NdnFib> () != 0);

  NdnApp::StopApplication ();
}


void
NdnProducer::OnInterest (const Ptr<const NdnInterestHeader> &interest, Ptr<Packet> origPacket)
{
  NdnApp::OnInterest (interest, origPacket); // tracing inside

  NS_LOG_FUNCTION (this << interest);

  if (!m_active) return;
    
  static NdnContentObjectTail tail;
  Ptr<NdnContentObjectHeader> header = Create<NdnContentObjectHeader> ();
  header->SetName (Create<NdnNameComponents> (interest->GetName ()));
  header->GetSignedInfo ().SetTimestamp (Simulator::Now ());
  header->GetSignature ().SetSignatureBits (m_signatureBits);

  NS_LOG_INFO ("node("<< GetNode()->GetId() <<") respodning with ContentObject:\n" << boost::cref(*header));
  
  Ptr<Packet> packet = Create<Packet> (m_virtualPayloadSize);
  // Ptr<const WeightsPathStretchTag> tag = origPacket->RemovePacketTag<WeightsPathStretchTag> ();
  // if (tag != 0)
  //   {
  //     // std::cout << Simulator::Now () << ", " << m_app->GetInstanceTypeId ().GetName () << "\n";

  //     // echo back WeightsPathStretchTag
  //     packet->AddPacketTag (CreateObject<WeightsPathStretchTag> (*tag));

  //     // \todo
  //     // packet->AddPacketTag should actually accept Ptr<const WeightsPathStretchTag> instead of
  //     // Ptr<WeightsPathStretchTag>.  Echoing will be simplified after change is done
  //   }
  
  packet->AddHeader (*header);
  packet->AddTrailer (tail);

  m_protocolHandler (packet);
  
  m_transmittedContentObjects (header, packet, this, m_face);
}

} // namespace ns3
