/* -*-  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.hpp"
#include "ns3/log.h"
#include "ns3/ndn-interest.hpp"
#include "ns3/ndn-data.hpp"
#include "ns3/string.h"
#include "ns3/uinteger.h"
#include "ns3/packet.h"
#include "ns3/simulator.h"

#include "ns3/ndn-app-face.hpp"
#include "ns3/ndn-fib.hpp"

#include "ns3/ndnSIM/utils/ndn-fw-hop-count-tag.hpp"

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

NS_LOG_COMPONENT_DEFINE("ndn.Producer");

namespace ns3 {
namespace ndn {

NS_OBJECT_ENSURE_REGISTERED(Producer);

TypeId
Producer::GetTypeId(void)
{
  static TypeId tid =
    TypeId("ns3::ndn::Producer")
      .SetGroupName("Ndn")
      .SetParent<App>()
      .AddConstructor<Producer>()
      .AddAttribute("Prefix", "Prefix, for which producer has the data", StringValue("/"),
                    MakeNameAccessor(&Producer::m_prefix), MakeNameChecker())
      .AddAttribute(
         "Postfix",
         "Postfix that is added to the output data (e.g., for adding producer-uniqueness)",
         StringValue("/"), MakeNameAccessor(&Producer::m_postfix), MakeNameChecker())
      .AddAttribute("PayloadSize", "Virtual payload size for Content packets", UintegerValue(1024),
                    MakeUintegerAccessor(&Producer::m_virtualPayloadSize),
                    MakeUintegerChecker<uint32_t>())
      .AddAttribute("Freshness", "Freshness of data packets, if 0, then unlimited freshness",
                    TimeValue(Seconds(0)), MakeTimeAccessor(&Producer::m_freshness),
                    MakeTimeChecker())
      .AddAttribute(
         "Signature",
         "Fake signature, 0 valid signature (default), other values application-specific",
         UintegerValue(0), MakeUintegerAccessor(&Producer::m_signature),
         MakeUintegerChecker<uint32_t>())
      .AddAttribute("KeyLocator",
                    "Name to be used for key locator.  If root, then key locator is not used",
                    NameValue(), MakeNameAccessor(&Producer::m_keyLocator), MakeNameChecker());
  return tid;
}

Producer::Producer()
{
  // NS_LOG_FUNCTION_NOARGS ();
}

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

  App::StartApplication();

  NS_LOG_DEBUG("NodeID: " << GetNode()->GetId());

  Ptr<Fib> fib = GetNode()->GetObject<Fib>();

  Ptr<fib::Entry> fibEntry = fib->Add(m_prefix, m_face, 0);

  fibEntry->UpdateStatus(m_face, fib::FaceMetric::NDN_FIB_GREEN);

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

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

  App::StopApplication();
}

void
Producer::OnInterest(Ptr<const Interest> interest)
{
  App::OnInterest(interest); // tracing inside

  NS_LOG_FUNCTION(this << interest);

  if (!m_active)
    return;

  Ptr<Data> data = Create<Data>(Create<Packet>(m_virtualPayloadSize));
  Ptr<Name> dataName = Create<Name>(interest->GetName());
  dataName->append(m_postfix);
  data->SetName(dataName);
  data->SetFreshness(m_freshness);
  data->SetTimestamp(Simulator::Now());

  data->SetSignature(m_signature);
  if (m_keyLocator.size() > 0) {
    data->SetKeyLocator(Create<Name>(m_keyLocator));
  }

  NS_LOG_INFO("node(" << GetNode()->GetId() << ") respodning with Data: " << data->GetName());

  // Echo back FwHopCountTag if exists
  FwHopCountTag hopCountTag;
  if (interest->GetPayload()->PeekPacketTag(hopCountTag)) {
    data->GetPayload()->AddPacketTag(hopCountTag);
  }

  m_face->ReceiveData(data);
  m_transmittedDatas(data, this, m_face);
}

} // namespace ndn
} // namespace ns3
