/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/*
 * Copyright (c) 2011 UCLA
 *
 * 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-trace-helper.h"

#include "ns3/config.h"
#include "ns3/callback.h"
#include "ns3/ccnx-app.h"
#include "ns3/ccnx-face.h"
#include "ns3/packet.h"
#include "ns3/log.h"
#include "ns3/assert.h"
#include "ns3/node-list.h"
#include "ns3/object-vector.h"
#include "ns3/simulator.h"
#include "ns3/names.h"
#include "ns3/tcp-l4-protocol.h"
#include "ns3/node.h"

#include <boost/ref.hpp>
#include <boost/lexical_cast.hpp>

#include "tracers/ccnx-aggregate-app-tracer.h"
#include "tracers/ccnx-aggregate-l3-tracer.h"
#include "tracers/ccnx-rate-l3-tracer.h"
#include "tracers/ccnx-seqs-app-tracer.h"
#include "tracers/ipv4-rate-l3-tracer.h"
#include "tracers/ipv4-seqs-app-tracer.h"
#include "tracers/ccnx-consumer-window-tracer.h"
#include "tracers/ccnx-path-weight-tracer.h"

#include "ns3/ccnx-interest-header.h"
#include "ns3/ccnx-content-object-header.h"

#include <fstream>

using namespace std;
using namespace boost;

NS_LOG_COMPONENT_DEFINE ("CcnxTraceHelper");

namespace ns3 {

CcnxTraceHelper::CcnxTraceHelper ()
  : m_l3RateTrace (0)
  , m_appSeqsTrace (0)
  , m_ipv4AppSeqsTrace (0)
  , m_windowsTrace (0)
  , m_windowsTcpTrace (0)
  , m_pathWeightsTrace (0)
{
}

CcnxTraceHelper::~CcnxTraceHelper ()
{
  NS_LOG_FUNCTION (this);
  if (m_l3RateTrace != 0) delete m_l3RateTrace;
  if (m_appSeqsTrace != 0) delete m_appSeqsTrace;
  if (m_ipv4AppSeqsTrace != 0) delete m_ipv4AppSeqsTrace;
  if (m_windowsTrace != 0) delete m_windowsTrace;
  if (m_windowsTcpTrace != 0) delete m_windowsTcpTrace;
  if (m_pathWeightsTrace != 0) delete m_pathWeightsTrace;
  if (m_ipv4RateTrace != 0) delete m_ipv4RateTrace;
  
  if (m_apps.size () > 0)
    {
      ofstream of;
      if (!m_appTrace.empty ())
        {
          of.open (m_appTrace.c_str (), ios_base::trunc | ios_base::out);
          of << "# ";
          m_apps.front ()->PrintHeader (of);
          of << "\n";
        }
      
      for (std::list<Ptr<CcnxAppTracer> >::iterator app = m_apps.begin ();
           app != m_apps.end ();
           app++)
        {
          if (!m_appTrace.empty ())
            {
              (*app)->Print (of);
              of << "\n";
            }
          else
            {
              NS_LOG_INFO (*(*app));
            }
        }
    }

  if (m_l3s.size () > 0)
    {
      ofstream of;
      if (!m_l3Trace.empty ())
        {
          of.open (m_l3Trace.c_str (), ios_base::trunc | ios_base::out);
          of << "# ";
          m_l3s.front ()->PrintHeader (of);
          of << "\n";
        }
      
      for (std::list<Ptr<CcnxL3Tracer> >::iterator l3 = m_l3s.begin ();
           l3 != m_l3s.end ();
           l3++)
        {
          if (!m_l3Trace.empty ())
            {
              (*l3)->Print (of);
              of << "\n";
            }
          else
            {
              NS_LOG_INFO (*(*l3));
            }
        }
    }
}

void
CcnxTraceHelper::SetAppTraceFile (const std::string &appTrace)
{
  NS_LOG_FUNCTION (this << appTrace);
  m_appTrace = appTrace;
}

void
CcnxTraceHelper::SetL3TraceFile (const std::string &l3Trace)
{
  NS_LOG_FUNCTION (this << l3Trace);
  m_l3Trace = l3Trace;
}

void
CcnxTraceHelper::EnableAggregateAppAll (const std::string &appName)
{
  NS_LOG_FUNCTION (this << appName);
  for (NodeList::Iterator node = NodeList::Begin ();
       node != NodeList::End ();
       node++)
    {
      ObjectVectorValue apps;
      (*node)->GetAttribute ("ApplicationList", apps);

      NS_LOG_DEBUG ("Node: " << lexical_cast<string> ((*node)->GetId ()));
      
      uint32_t appId = 0;
      for (ObjectVectorValue::Iterator app = apps.Begin ();
           app != apps.End ();
           app++, appId++)
        {
          NS_LOG_DEBUG ("App: " << lexical_cast<string> (appId) << ", typeId: " << (*app)->GetInstanceTypeId ().GetName ());
          if ((*app)->GetInstanceTypeId ().GetName () == appName)
            {
              m_apps.push_back (Create<CcnxAggregateAppTracer> (appName,
                                                                *node,
                                                                lexical_cast<string> (appId)));
            }
        }
    }
}

void
CcnxTraceHelper::EnableAggregateL3All ()
{
  NS_LOG_FUNCTION (this);
  
  for (NodeList::Iterator node = NodeList::Begin ();
       node != NodeList::End ();
       node++)
    {
      NS_LOG_DEBUG ("Node: " << lexical_cast<string> ((*node)->GetId ()));
      
      m_l3s.push_back (Create<CcnxAggregateL3Tracer> (*node));
    }
}

void
CcnxTraceHelper::EnableRateL3All (const std::string &l3RateTrace)
{
  NS_LOG_FUNCTION (this);
  m_l3RateTrace = new ofstream (l3RateTrace.c_str (), ios::trunc);

  for (NodeList::Iterator node = NodeList::Begin ();
       node != NodeList::End ();
       node++)
    {
      NS_LOG_DEBUG ("Node: " << lexical_cast<string> ((*node)->GetId ()));

      Ptr<CcnxRateL3Tracer> trace = Create<CcnxRateL3Tracer> (boost::ref(*m_l3RateTrace), *node);
      trace->SetAveragingPeriod (Seconds (0.2));
      m_l3Rates.push_back (trace);
    }

  if (m_l3Rates.size () > 0)
    {
      // *m_l3RateTrace << "# "; // not necessary for R's read.table
      m_l3Rates.front ()->PrintHeader (*m_l3RateTrace);
      *m_l3RateTrace << "\n";
    }
}

void
CcnxTraceHelper::EnableIpv4RateL3All (const std::string &file)
{
  NS_LOG_FUNCTION (this);
  m_ipv4RateTrace = new ofstream (file.c_str (), ios::trunc);

  for (NodeList::Iterator node = NodeList::Begin ();
       node != NodeList::End ();
       node++)
    {
      NS_LOG_DEBUG ("Node: " << lexical_cast<string> ((*node)->GetId ()));

      Ptr<Ipv4RateL3Tracer> trace = Create<Ipv4RateL3Tracer> (boost::ref(*m_ipv4RateTrace), *node);
      trace->SetAveragingPeriod (Seconds (0.2));
      m_ipv4Rates.push_back (trace);
    }

  if (m_ipv4Rates.size () > 0)
    {
      // *m_ipv4RateTrace << "# "; // not necessary for R's read.table
      m_ipv4Rates.front ()->PrintHeader (*m_ipv4RateTrace);
      *m_ipv4RateTrace << "\n";
    }
}


void
CcnxTraceHelper::EnableSeqsAppAll (const std::string &appName, const std::string &trace)
{
  NS_LOG_FUNCTION (this);
  m_appSeqsTrace = new ofstream (trace.c_str (), ios::trunc);

  for (NodeList::Iterator node = NodeList::Begin ();
       node != NodeList::End ();
       node++)
    {
      ObjectVectorValue apps;
      (*node)->GetAttribute ("ApplicationList", apps);

      NS_LOG_DEBUG ("Node: " << lexical_cast<string> ((*node)->GetId ()));
      
      uint32_t appId = 0;
      for (ObjectVectorValue::Iterator app = apps.Begin ();
           app != apps.End ();
           app++, appId++)
        {
          NS_LOG_DEBUG ("App: " << lexical_cast<string> (appId) << ", typeId: " << (*app)->GetInstanceTypeId ().GetName ());
          if ((*app)->GetInstanceTypeId ().GetName () == appName)
            {
              Ptr<CcnxSeqsAppTracer> trace = Create<CcnxSeqsAppTracer> (boost::ref(*m_appSeqsTrace),
                                                                        appName,
                                                                        *node,
                                                                        lexical_cast<string> (appId));
              m_appSeqs.push_back (trace);
            }
        }
      
    }

  if (m_appSeqs.size () > 0)
    {
      // *m_l3RateTrace << "# "; // not necessary for R's read.table
      m_appSeqs.front ()->PrintHeader (*m_appSeqsTrace);
      *m_appSeqsTrace << "\n";
    }
}

void
CcnxTraceHelper::EnableIpv4SeqsAppAll (const std::string &trace)
{
  NS_LOG_FUNCTION (this);
  m_ipv4AppSeqsTrace = new ofstream (trace.c_str (), ios::trunc);

  for (NodeList::Iterator node = NodeList::Begin ();
       node != NodeList::End ();
       node++)
    {
      ObjectVectorValue apps;
      (*node)->GetAttribute ("ApplicationList", apps);

      NS_LOG_DEBUG ("Node: " << lexical_cast<string> ((*node)->GetId ()));
      
      uint32_t appId = 0;
      for (ObjectVectorValue::Iterator app = apps.Begin ();
           app != apps.End ();
           app++, appId++)
        {
          NS_LOG_DEBUG ("App: " << lexical_cast<string> (appId) << ", typeId: " << (*app)->GetInstanceTypeId ().GetName ());
          if ((*app)->GetInstanceTypeId ().GetName () == "ns3::PacketSink" ||
              (*app)->GetInstanceTypeId ().GetName () == "ns3::BulkSendApplication")
            {
              Ptr<Ipv4SeqsAppTracer> trace = Create<Ipv4SeqsAppTracer> (boost::ref(*m_ipv4AppSeqsTrace),
                                                                        *node,
                                                                        lexical_cast<string> (appId));
              m_ipv4AppSeqs.push_back (trace);
            }
        }
      
    }

  if (m_ipv4AppSeqs.size () > 0)
    {
      m_ipv4AppSeqs.front ()->PrintHeader (*m_ipv4AppSeqsTrace);
      *m_ipv4AppSeqsTrace << "\n";
    }
}

void
CcnxTraceHelper::EnableWindowsAll (const std::string &windowTrace)
{
  NS_LOG_FUNCTION (this);
  m_windowsTrace = new ofstream (windowTrace.c_str (), ios::trunc);

  for (NodeList::Iterator node = NodeList::Begin ();
       node != NodeList::End ();
       node++)
    {
      ObjectVectorValue apps;
      (*node)->GetAttribute ("ApplicationList", apps);

      NS_LOG_DEBUG ("Node: " << lexical_cast<string> ((*node)->GetId ()));
      
      uint32_t appId = 0;
      for (ObjectVectorValue::Iterator app = apps.Begin ();
           app != apps.End ();
           app++, appId++)
        {
          if ((*app)->GetInstanceTypeId ().GetName () == "ns3::CcnxConsumerWindow")
            {
              Ptr<CcnxConsumerWindowTracer> trace = Create<CcnxConsumerWindowTracer> (boost::ref(*m_windowsTrace),
                                                                                      *node,
                                                                                      lexical_cast<string> (appId));
              m_windows.push_back (trace);
            }
        }
      
    }

  if (m_windows.size () > 0)
    {
      m_windows.front ()->PrintHeader (*m_windowsTrace);
      *m_windowsTrace << "\n";
    }
}

void
CcnxTraceHelper::TcpConnect (Ptr<Node> node)
{
  ObjectVectorValue sockets;
  node->GetObject<TcpL4Protocol> ()->GetAttribute ("SocketList", sockets);
  
  uint32_t sockId = 0;      
  for (ObjectVectorValue::Iterator socket = sockets.Begin ();
       socket != sockets.End ();
       socket++, sockId++)
    {
      // std::cout << "Node: " << node->GetId () << ", Socket " << sockId << "\n";
          
      Ptr<TcpCongestionWindowTracer> trace = Create<TcpCongestionWindowTracer> (boost::ref(*m_windowsTcpTrace),
                                                                                node,
                                                                                lexical_cast<string> (sockId));
      m_windowsTcp.push_back (trace);
    }
}

void
CcnxTraceHelper::EnableWindowsTcpAll (const std::string &windowTrace)
{
  NS_LOG_FUNCTION (this);
  m_windowsTcpTrace = new ofstream (windowTrace.c_str (), ios::trunc);

  WindowTracer::PrintHeader (*m_windowsTcpTrace);
  *m_windowsTcpTrace << "\n";
}

void
CcnxTraceHelper::EnablePathWeights (const std::string &pathWeights)
{
  NS_LOG_FUNCTION (this);
  m_pathWeightsTrace = new ofstream (pathWeights.c_str (), ios::trunc);

  CcnxPathWeightTracer::PrintHeader (*m_pathWeightsTrace);
  *m_pathWeightsTrace << "\n";

  for (NodeList::Iterator node = NodeList::Begin ();
       node != NodeList::End ();
       node++)
    {
      Ptr<CcnxPathWeightTracer> trace = Create<CcnxPathWeightTracer> (boost::ref(*m_pathWeightsTrace),
                                                                      *node);
      m_pathWeights.push_back (trace);
    }
}

} // namespace ns3
