/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2010 Hajime Tazaki
 *
 * 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: Hajime Tazaki (tazaki@sfc.wide.ad.jp)
 *         Ilya Moiseenko <iliamo@cs.ucla.edu>
 */

#include "rocketfuel-weights-reader.h"

#include "ns3/nstime.h"
#include "ns3/log.h"
#include "ns3/assert.h"
#include "ns3/names.h"
#include "ns3/net-device-container.h"
#include "ns3/point-to-point-helper.h"
#include "ns3/point-to-point-net-device.h"
#include "ns3/internet-stack-helper.h"
#include "ns3/ipv4-address-helper.h"
#include "ns3/ipv4-global-routing-helper.h"
#include "ns3/drop-tail-queue.h"
#include "ns3/ipv4-interface.h"
#include "ns3/ipv4.h"
#include "ns3/string.h"
#include "ns3/pointer.h"
#include "ns3/uinteger.h"
#include "ns3/ipv4-address.h"

#include "ns3/mobility-model.h"

#include <regex.h>

#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>
#include "../utils/spring-mobility-helper.h"

#include <iomanip>
#include <set>

using namespace std;

NS_LOG_COMPONENT_DEFINE ("RocketfuelWeightsReader");

namespace ns3 {
    
RocketfuelWeightsReader::RocketfuelWeightsReader (const std::string &path/*=""*/)
  : AnnotatedTopologyReader (path)
{
  NS_LOG_FUNCTION (this);
  SetMobilityModel ("ns3::SpringMobilityModel");
}
    
RocketfuelWeightsReader::~RocketfuelWeightsReader ()
{
  NS_LOG_FUNCTION (this);
}

void
RocketfuelWeightsReader::SetFileType (uint8_t inputType)
{
  m_inputType = inputType;
}

NodeContainer
RocketfuelWeightsReader::Read ()
{
  if (m_inputType == POSITIONS)
    return AnnotatedTopologyReader::Read ();
  
  ifstream topgen;
  topgen.open (GetFileName ().c_str ());
        
  if ( !topgen.is_open () )
    {
      NS_LOG_ERROR ("Cannot open file " << GetFileName () << " for reading");
      return m_nodes;
    }

  map<string, set<string> > processedLinks; // to eliminate duplications
  bool repeatedRun = LinksSize () > 0;
  std::list<Link>::iterator linkIterator = m_linksList.begin ();
  
  while (!topgen.eof ())
    {
      string line;
      getline (topgen,line);
      if (line == "") continue;
      if (line[0] == '#') continue; // comments

      // NS_LOG_DEBUG ("Input: [" << line << "]");
      
      istringstream lineBuffer (line);
      string from, to, attribute;

      lineBuffer >> from >> to >> attribute;

      if (processedLinks[to].size () != 0 &&
          processedLinks[to].find (from) != processedLinks[to].end ())
        {
          continue; // duplicated link
        }
      processedLinks[from].insert (to);
      
      Ptr<Node> fromNode = Names::Find<Node> (m_path, from);
      if (fromNode == 0)
        {
          fromNode = CreateNode (from);
        }

      Ptr<Node> toNode   = Names::Find<Node> (m_path, to);
      if (toNode == 0)
        {
          toNode = CreateNode (to);
        }

      Link *link;
      if (!repeatedRun)
        link = new Link (fromNode, from, toNode, to);
      else
        {
          NS_ASSERT (linkIterator != m_linksList.end ());
          link = &(*linkIterator);

          linkIterator++;
        }

      switch (m_inputType)
        {
        case WEIGHTS:
          {
            uint16_t metric = boost::lexical_cast<uint16_t> (attribute);
            link->SetAttribute ("OSPF", boost::lexical_cast<string> (metric));
            break;
          }
        case LATENCIES:
          link->SetAttribute ("Delay", attribute);
          break;
        default:
          ; //
        }

      NS_LOG_DEBUG ("Link " << from << " <==> " << to << " / " << attribute);
      if (!repeatedRun)
        {
          AddLink (*link);
          delete link;
        }
    }
        
  topgen.close ();

  if (!repeatedRun)
    {
      NS_LOG_INFO ("Rocketfuel topology created with " << m_nodes.GetN () << " nodes and " << LinksSize () << " links");
    }
  return m_nodes;
}

void
RocketfuelWeightsReader::Commit ()
{
  ApplySettings ();

  SpringMobilityHelper::InstallSprings (LinksBegin (), LinksEnd ());
}

void
RocketfuelWeightsReader::SavePositions (const std::string &file) const
{
  ofstream os (file.c_str (), ios::trunc);
  os << "router\n";
  
  for (NodeContainer::Iterator node = m_nodes.Begin ();
       node != m_nodes.End ();
       node++)
    {
      std::string name = Names::FindName (*node);
      Ptr<MobilityModel> mobility = (*node)->GetObject<MobilityModel> ();
      Vector position = mobility->GetPosition ();

      os << name << "\t" << "unknown" << "\t" << -position.y << "\t" << position.x << "\n";
    }
}

// void
// RocketfuelWeightsReader::Cheat (NodeContainer &nodes)
// {
//   double epsilon = 1;

//   for (NodeContainer::Iterator i = nodes.Begin ();
//        i != nodes.End ();
//        i++)
//     {
      
//     }  
// }

} /* namespace ns3 */
