/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2013 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>
 *       : Saran Tarnoi <saran.tarnoi@gmail.com>
 */

#include "ndn-link-control-helper.hpp"

#include "ns3/assert.h"
#include "ns3/names.h"
#include "ns3/point-to-point-net-device.h"
#include "ns3/point-to-point-channel.h"
#include "ns3/channel.h"
#include "ns3/log.h"
#include "ns3/error-model.h"
#include "ns3/string.h"
#include "ns3/boolean.h"
#include "ns3/double.h"
#include "ns3/pointer.h"

#include "model/ndn-l3-protocol.hpp"
#include "model/ndn-net-device-face.hpp"

#include "fw/forwarder.hpp"

NS_LOG_COMPONENT_DEFINE("ndn.LinkControlHelper");

namespace ns3 {
namespace ndn {

void
LinkControlHelper::setErrorRate(Ptr<Node> node1, Ptr<Node> node2, double errorRate)
{
  NS_LOG_FUNCTION(node1 << node2 << errorRate);

  NS_ASSERT(node1 != nullptr && node2 != nullptr);
  NS_ASSERT(errorRate <= 1.0);

  Ptr<ndn::L3Protocol> ndn1 = node1->GetObject<ndn::L3Protocol>();
  Ptr<ndn::L3Protocol> ndn2 = node2->GetObject<ndn::L3Protocol>();

  NS_ASSERT(ndn1 != nullptr && ndn2 != nullptr);

  // iterate over all faces to find the right one
  for (const auto& face : ndn1->getForwarder()->getFaceTable()) {
    shared_ptr<ndn::NetDeviceFace> ndFace = std::dynamic_pointer_cast<NetDeviceFace>(face);
    if (ndFace == nullptr)
      continue;

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

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

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

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

    ObjectFactory errorFactory("ns3::RateErrorModel");
    errorFactory.Set("ErrorUnit", StringValue("ERROR_UNIT_PACKET"));
    errorFactory.Set("ErrorRate", DoubleValue(errorRate));
    if (errorRate <= 0) {
      errorFactory.Set("IsEnabled", BooleanValue(false));
    }

    nd1->SetAttribute("ReceiveErrorModel", PointerValue(errorFactory.Create<ErrorModel>()));
    nd2->SetAttribute("ReceiveErrorModel", PointerValue(errorFactory.Create<ErrorModel>()));
  }
}

void
LinkControlHelper::FailLink(Ptr<Node> node1, Ptr<Node> node2)
{
  setErrorRate(node1, node2, 1.0);
}

void
LinkControlHelper::FailLinkByName(const std::string& node1, const std::string& node2)
{
  FailLink(Names::Find<Node>(node1), Names::Find<Node>(node2));
}

void
LinkControlHelper::UpLink(Ptr<Node> node1, Ptr<Node> node2)
{
  setErrorRate(node1, node2, -0.1); // this will ensure error model is disabled
}

void
LinkControlHelper::UpLinkByName(const std::string& node1, const std::string& node2)
{
  UpLink(Names::Find<Node>(node1), Names::Find<Node>(node2));
}

} // namespace ndn
} // namespace ns3
