/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
 * Copyright (c) 2012 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: Zhenkai Zhu <zhenkai@cs.ucla.edu>
 *         卞超轶 Chaoyi Bian <bcy@pku.edu.cn>
 *	   Alexander Afanasyev <alexander.afanasyev@ucla.edu>
 */

#include "sync-interest-table.h"
#include "sync-log.h"
using namespace std;
using namespace boost;

INIT_LOGGER ("SyncInterestTable");

namespace Sync
{

SyncInterestTable::SyncInterestTable ()
{
  m_scheduler.schedule (posix_time::seconds (4),
                        bind (&SyncInterestTable::expireInterests, this),
                        0);
}

SyncInterestTable::~SyncInterestTable ()
{
}

vector<string>
SyncInterestTable::fetchAll ()
{
  expireInterests ();
  recursive_mutex::scoped_lock lock (m_mutex);
  
  vector<string> entries;
  for (unordered_map<string, time_t>::iterator it = m_table.begin();
       it != m_table.end();
       ++it)
    {
      entries.push_back(it->first);
    }
  m_table.clear ();

  return entries;
}

bool
SyncInterestTable::insert(const string &interest)
{
  recursive_mutex::scoped_lock lock (m_mutex);
  TableContainer::iterator it = m_table.find (interest);
  if (it != m_table.end())
    m_table.erase(it);
  time_t currentTime = time(0);
  m_table.insert (make_pair(interest, currentTime));
}

uint32_t
SyncInterestTable::size () const
{
  recursive_mutex::scoped_lock lock (m_mutex);
  return m_table.size ();
}

bool
SyncInterestTable::remove (const std::string &interest)
{
  recursive_mutex::scoped_lock lock (m_mutex);
  TableContainer::iterator item = m_table.find (interest);
  if (item != m_table.end ())
    {
      m_table.erase (item);
      return true;
    }
  return false;
}


void SyncInterestTable::expireInterests ()
{ 
  recursive_mutex::scoped_lock lock (m_mutex);

  uint32_t count = 0;
  time_t currentTime = time(0);
  TableContainer::iterator it = m_table.begin (); 
  while (it != m_table.end())
    {
    time_t timestamp = it->second;
    _LOG_DEBUG ("expireInterests (): " << timestamp << ", " << currentTime);
    if (currentTime - timestamp > m_checkPeriod)
      {
        it = m_table.erase (it);
        count ++;
      }
    else
      ++it;
  }

  _LOG_DEBUG ("expireInterests (): expired " << count);
  
  m_scheduler.schedule (posix_time::seconds (4),
                        bind (&SyncInterestTable::expireInterests, this),
                        0);
}


}
