/* -*- 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 "ccnx-pit-entry.h"
#include "ccnx-name-components.h"
#include "ccnx-fib.h"
#include "ccnx-interest-header.h"

#include "ns3/simulator.h"
#include "ns3/log.h"

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

NS_LOG_COMPONENT_DEFINE ("CcnxPitEntry");

namespace ns3
{

CcnxPitEntry::CcnxPitEntry (CcnxPit &container,
                            Ptr<const CcnxInterestHeader> header,
                            Ptr<CcnxFibEntry> fibEntry)
  : m_container (container)
  , m_prefix (header->GetNamePtr ())
  , m_expireTime (Simulator::Now () + header->GetInterestLifetime ())
  , m_fibEntry (fibEntry)
  , m_maxRetxCount (0)
{
  // note that if interest lifetime is not set, the behavior is undefined
}

void
CcnxPitEntry::SetExpireTime (const Time &expireTime)
{
  NS_LOG_FUNCTION (expireTime.ToDouble (Time::S));
  m_expireTime = expireTime;
}

void
CcnxPitEntry::UpdateLifetime (const Time &offsetTime)
{
  NS_LOG_FUNCTION (offsetTime.ToDouble (Time::S));
  
  Time newExpireTime = Simulator::Now () + offsetTime;
  if (newExpireTime > m_expireTime)
    m_expireTime = newExpireTime;
  
  NS_LOG_INFO ("Updated lifetime to " << m_expireTime.ToDouble (Time::S));
}

CcnxPitEntry::in_iterator
CcnxPitEntry::AddIncoming (Ptr<CcnxFace> face)
{
  std::pair<in_iterator,bool> ret = 
    m_incoming.insert (CcnxPitEntryIncomingFace (face));

  NS_ASSERT_MSG (ret.second, "Something is wrong");

  return ret.first;
}

void
CcnxPitEntry::RemoveIncoming (Ptr<CcnxFace> face)
{
  m_incoming.erase (face);
}


CcnxPitEntry::out_iterator
CcnxPitEntry::AddOutgoing (Ptr<CcnxFace> face)
{
  std::pair<out_iterator,bool> ret =
    m_outgoing.insert (CcnxPitEntryOutgoingFace (face));

  if (!ret.second)
    { // outgoing face already exists
      m_outgoing.modify (ret.first,
                         ll::bind (&CcnxPitEntryOutgoingFace::UpdateOnRetransmit, ll::_1));
    }

  return ret.first;
}

void
CcnxPitEntry::RemoveAllReferencesToFace (Ptr<CcnxFace> face)
{
  in_iterator incoming = m_incoming.find (face);

  if (incoming != m_incoming.end ())
    m_incoming.erase (incoming);

  out_iterator outgoing =
    m_outgoing.find (face);

  if (outgoing != m_outgoing.end ())
    m_outgoing.erase (outgoing);
}

void
CcnxPitEntry::SetWaitingInVain (CcnxPitEntry::out_iterator face)
{
  NS_LOG_DEBUG (boost::cref (*face->m_face));

  m_outgoing.modify (face,
                     (&ll::_1)->*&CcnxPitEntryOutgoingFace::m_waitingInVain = true);
}

bool
CcnxPitEntry::AreAllOutgoingInVain () const
{
  NS_LOG_DEBUG (m_outgoing.size ());

  bool inVain = true;
  std::for_each (m_outgoing.begin (), m_outgoing.end (),
                 ll::var(inVain) &= (&ll::_1)->*&CcnxPitEntryOutgoingFace::m_waitingInVain);

  NS_LOG_DEBUG ("inVain " << inVain);
  return inVain;
}

bool
CcnxPitEntry::AreTherePromisingOutgoingFacesExcept (Ptr<CcnxFace> face) const
{
  bool inVain = true;
  std::for_each (m_outgoing.begin (), m_outgoing.end (),
                 ll::var(inVain) &=
                 ((&ll::_1)->*&CcnxPitEntryOutgoingFace::m_face == face ||
                  (&ll::_1)->*&CcnxPitEntryOutgoingFace::m_waitingInVain));

  return !inVain;
}

void
CcnxPitEntry::IncreaseAllowedRetxCount ()
{
  NS_LOG_ERROR (this);
  if (Simulator::Now () - m_lastRetransmission >= MilliSeconds (100))
    {
      // cheat:
      // don't allow retransmission faster than every 100ms
      m_maxRetxCount++;
      m_lastRetransmission = Simulator::Now ();
    }
}

std::ostream& operator<< (std::ostream& os, const CcnxPitEntry &entry)
{
  os << "Prefix: " << *entry.m_prefix << "\n";
  os << "In: ";
  bool first = true;
  BOOST_FOREACH (const CcnxPitEntryIncomingFace &face, entry.m_incoming)
    {
      if (!first)
        os << ",";
      else
        first = false;
      
      os << *face.m_face;
    }

  os << "\nOut: ";
  first = true;
  BOOST_FOREACH (const CcnxPitEntryOutgoingFace &face, entry.m_outgoing)
    {
      if (!first)
        os << ",";
      else
        first = false;
      
      os << *face.m_face;
    }
  os << "\nNonces: ";
  first = true;
  BOOST_FOREACH (uint32_t nonce, entry.m_seenNonces)
    {
      if (!first)
        os << ",";
      else
        first = false;
      
      os << nonce;
    }

  return os;
}


}
