/* -*-  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>
 */
 
 
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/NDNabstraction-module.h"
#include "ns3/point-to-point-grid.h"
#include "ns3/ipv4-global-routing-helper.h"
#include "ns3/random-variable.h"
#include "ns3/ccnx.h"
#include "ns3/topology-reader.h"
#include "../model/ccnx-net-device-face.h"

#include <iostream>
#include <sstream>
#include <map>
#include <list>
#include <set>
#include "ns3/rocketfuel-topology-reader.h"

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

using namespace ns3;
using namespace std;
using namespace boost;

NS_LOG_COMPONENT_DEFINE ("LinkFailureSprint");

#include "base-experiment.h"

class Experiment : public BaseExperiment
{
public:
  typedef tuple<string, string> failure_t;
  typedef list<failure_t> failures_t;
  
  Experiment (const string &file)
  {
    ifstream failures (("./src/NDNabstraction/examples/failures/failures-"+file).c_str ());
    for(std::string line; std::getline(failures, line); )
      {
        if (line == "")
          {
            m_failures.push_back (failures_t ());
            continue;
          }

        failures_t failures;
        istringstream run (line);
        while (!run.eof () && !run.bad ())
          {
            int32_t link1 = -1;
            int32_t link2 = -1;
            run >> link1;
            run.get ();
            run >> link2;
            run.get ();
            if (link1 < 0 || link2 < 0) continue;

            // cout << link1 << " <-> " << link2 << "   ";
            failures.push_back (failure_t (lexical_cast<string> (link1), lexical_cast<string> (link2)));
          }
        m_failures.push_back (failures);
      }
  }
  
  // hijacker is more than an application. just disable all faces
  void
  FailLinks (uint32_t failId)
  {
    failures_t failures = m_failures [failId];
    BOOST_FOREACH (failure_t failure, failures)
      {
        Ptr<Node> node1 = Names::Find<Node> ("/sprint", failure.get<0> ());
        Ptr<Node> node2 = Names::Find<Node> ("/sprint", failure.get<1> ());
        // cout << failure.get<0> () << " <-> " << failure.get<1> () << "   ";
        // cout << node1 << ", " << node2 << "\n";

        Ptr<Ccnx> ccnx1 = node1->GetObject<Ccnx> ();
        Ptr<Ccnx> ccnx2 = node2->GetObject<Ccnx> ();
        for (uint32_t faceId = 0; faceId < ccnx1->GetNFaces (); faceId++)
          {
            Ptr<CcnxFace> face = ccnx1->GetFace (faceId);
            Ptr<CcnxNetDeviceFace> ndFace = face->GetObject<CcnxNetDeviceFace> ();
            if (ndFace == 0) continue;

            Ptr<PointToPointNetDevice> nd1 = ndFace->GetNetDevice ()->GetObject<PointToPointNetDevice> ();
            if (nd1 == 0) continue;

            Ptr<Channel> channel = nd1->GetChannel ();
            if (channel == 0) continue;

            Ptr<PointToPointChannel> ppChannel = DynamicCast<PointToPointChannel> (channel);

            Ptr<NetDevice> nd2 = ppChannel->GetDevice (0);
            if (nd2->GetNode () == node1)
              nd2 = ppChannel->GetDevice (1);

            if (Names::FindName (nd2->GetNode ()) == failure.get<1> ())
              {
                cout << "Failing " << failure.get<0> () << " <-> " << failure.get<1> () << " link\n";

                Ptr<CcnxFace> face1 = ccnx1->GetFaceByNetDevice (nd1);
                Ptr<CcnxFace> face2 = ccnx2->GetFaceByNetDevice (nd2);

                face1->SetUp (false);
                face2->SetUp (false);

                // set metric to max (for GlobalRouter to know what we want)
                Ptr<Ipv4> ipv4_1 = ccnx1->GetObject<Ipv4> ();
                Ptr<Ipv4> ipv4_2 = ccnx2->GetObject<Ipv4> ();

                uint32_t if1 = ipv4_1->GetInterfaceForDevice (nd1);
                uint32_t if2 = ipv4_2->GetInterfaceForDevice (nd2);

                ipv4_1->SetMetric (if1, std::numeric_limits<uint16_t>::max ());
                ipv4_2->SetMetric (if2, std::numeric_limits<uint16_t>::max ());
                break;
              }
          }
      }
  }

  // void
  // FailLinks(double threshold)
  // {
  //   NS_LOG_INFO("Failing links");
  //   m_linkRand = UniformVariable(0, 1.0);
  //   double probability = 0.0;
    
  //   BOOST_FOREACH (const TopologyReader::Link &link, m_reader.GetLinks())
  //     {
  //       probability = m_linkRand.GetValue();
  //       NS_LOG_INFO ("Probability = " << probability);
        
  //       if(probability <= threshold)
  //         {
  //           Ptr<Node> fromNode = link.GetFromNode ();
  //           Ptr<Node> toNode = link.GetToNode ();
  //           NS_LOG_INFO("From node id = " << fromNode->GetId());
  //           NS_LOG_INFO("To node id = " << toNode->GetId());
            
  //           Ptr<CcnxL3Protocol> fromCcnx = fromNode->GetObject<CcnxL3Protocol> ();
  //           Ptr<CcnxL3Protocol> toCcnx = toNode->GetObject<CcnxL3Protocol> (); 
          
  //           Ptr<NetDevice> fromDevice = link.GetFromNetDevice ();
  //           Ptr<NetDevice> toDevice = link.GetToNetDevice ();
          
  //           Ptr<CcnxFace> fromFace = fromCcnx->GetFaceByNetDevice (fromDevice);
  //           Ptr<CcnxFace> toFace = toCcnx->GetFaceByNetDevice (toDevice);
          
  //           NS_LOG_INFO("From face id = " << fromFace->GetId());
  //           NS_LOG_INFO("To face id = " << toFace->GetId());
  //           fromFace->SetUp (false);
  //           toFace->SetUp (false);
            
  //           NS_LOG_INFO(fromFace->IsUp());
  //           NS_LOG_INFO(toFace->IsUp());
  //         }

  //     }
  //   /*
  //   uint32_t nodeId = m_rand.GetValue ();
  //   Ptr<Node> node = Names::Find<Node> ("/sprint", lexical_cast<string> (nodeId));
    
  //   Ptr<CcnxL3Protocol> ccnx = node->GetObject<CcnxL3Protocol> ();
  //   UniformVariable faceRandom = UniformVariable (0, ccnx->GetNFaces ());
  //   uint32_t faceId = faceRandom.GetValue();
  //   Ptr<CcnxFace> face = ccnx->GetFace (faceId);
  //   face->SetUp(false);
  //   */
  // }

  //We are creating "everybody-to-everybody" usage pattern
  ApplicationContainer
  AddApplications()
  {
    NS_LOG_INFO ("Adding applications");
    NS_LOG_INFO ("GetN = " << reader->GetNodes().GetN());

    double delay = 0;
    
    ApplicationContainer apps;
    for (uint32_t i = 0; i<reader->GetNodes().GetN(); i++)
    {
      NS_LOG_INFO("i="<<i);
      Ptr<Node> node1 = Names::Find<Node> ("/sprint", lexical_cast<string> (i));
        
      CcnxAppHelper producerHelper ("ns3::CcnxProducer");
      producerHelper.SetPrefix ("/" + lexical_cast<string> (node1->GetId ()));
        
      apps.Add (producerHelper.Install (node1));
            
      CcnxAppHelper consumerHelper ("ns3::CcnxConsumerBatches");
      consumerHelper.SetAttribute ("LifeTime", StringValue("100s"));
      consumerHelper.SetAttribute ("Batches", StringValue("0s 1 1s 1 2s 1 3s 1 6s 1 20s 1"));
      
      for(uint32_t j = 0; j<reader->GetNodes().GetN();j++)
      {
        NS_LOG_INFO("j="<<j);
        if(i==j)
          continue;
        
        Ptr<Node> node2 = Names::Find<Node> ("/sprint", lexical_cast<string> (j));
          
        consumerHelper.SetPrefix ("/" + lexical_cast<string> (node1->GetId ()) + "/" + lexical_cast<string> (node2->GetId ()));
        ApplicationContainer consumer = consumerHelper.Install (node2);
        consumer.Start (Seconds (delay));
        apps.Add (consumer);

        delay += 0.0001;
      }
    }
    
    return apps;
  }

  void
  RecalculateRouting ()
  {
    Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
  }

private:
  vector<failures_t> m_failures;
};

int 
main (int argc, char *argv[])
{
  cout << "Begin link failure scenario\n";

  Config::SetDefault ("ns3::PointToPointNetDevice::DataRate", StringValue ("100Mbps"));
  Config::SetDefault ("ns3::DropTailQueue::MaxPackets", StringValue ("2000"));
  Config::SetDefault ("ns3::RttEstimator::InitialEstimation", StringValue ("0.5s"));
  // Config::SetDefault ("ns3::RttEstimator::MaxMultiplier", StringValue ("16.0")); // original default is 64.0

  Config::SetDefault ("ns3::ConfigStore::Filename", StringValue ("attributes.xml"));
  Config::SetDefault ("ns3::ConfigStore::Mode", StringValue ("Save"));
  Config::SetDefault ("ns3::ConfigStore::FileFormat", StringValue ("Xml"));

  // Config::SetDefault ("ns3::CcnxConsumer::LifeTime", StringValue ("100s"));
  
  uint32_t maxRuns = 1;
  uint32_t startRun = 0;
  std::string failures = "";
  CommandLine cmd;
  cmd.AddValue ("start", "Initial run number", startRun);
  cmd.AddValue ("runs", "Number of runs", maxRuns);
  cmd.AddValue ("failures", "File with failures", failures);
  cmd.Parse (argc, argv);

  if (failures == "")
    {
      std::cerr << "--failures=<file> parameter has to be specified" << std::endl;
      return 1;
    }

  // ConfigStore config;
  // config.ConfigureDefaults ();

  Experiment experiment (failures);
  for (uint32_t run = startRun; run < startRun + maxRuns; run++)
    {
      Config::SetGlobal ("RngRun", IntegerValue (run));
      cout << "seed = " << SeedManager::GetSeed () << ", run = " << SeedManager::GetRun () << endl;

      cout << "Run " << run << endl;
      string prefix = "link-failure-" + lexical_cast<string> (run) + "-";
  
      experiment.ConfigureTopology ();
      experiment.InstallCcnxStack (true);
      ApplicationContainer apps = experiment.AddApplications ();
      cout << "Total number of applications: " << apps.GetN () << "\n";

      Simulator::Schedule (Seconds (10.0), &Experiment::FailLinks, &experiment, run);
      Simulator::Schedule (Seconds (39.0), &Experiment::RecalculateRouting, &experiment);

      //tracing
      CcnxTraceHelper traceHelper;
      Simulator::Schedule (Seconds (4.5), &CcnxTraceHelper::EnableSeqsAppAll, &traceHelper,
                           "ns3::CcnxConsumerBatches", prefix + "consumers-seqs.log");
      Simulator::Schedule (Seconds (4.5), &CcnxTraceHelper::EnablePathWeights, &traceHelper,
                           prefix + "weights.log");

      experiment.Run (Seconds(60.0));
    }

  cout << "Finish link failure scenario\n";
  return 0;
}
