/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2011-2015  Regents of the University of California.
 *
 * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
 * contributors.
 *
 * ndnSIM is free software: you can redistribute it and/or modify it under the terms
 * of the GNU General Public License as published by the Free Software Foundation,
 * either version 3 of the License, or (at your option) any later version.
 *
 * ndnSIM 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
 * ndnSIM, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 **/

// ndn-simple-with-content-freshness.cpp

#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/ndnSIM-module.h"

namespace ns3 {

/**
 * This scenario simulates a very simple network topology:
 *
 *
 *      +----------+     1Mbps      +--------+     1Mbps      +----------+
 *      | consumer | <------------> | router | <------------> | producer |
 *      +----------+         10ms   +--------+          10ms  +----------+
 *
 * This scenario demonstrates how to use content store that responds to Freshness parameter set in
 * data packets.  In other words, if the producer set FreshnessPeriod field to 2 seconds, the
 * corresponding data packet will not be considered fresh for more than 2 seconds (can be cached
 * for a shorter time, if entry is evicted earlier)
 *
 *     NS_LOG=OneInterestRequester ./waf --run ndn-simple-with-content-freshness
 */

int
main(int argc, char* argv[])
{
  // setting default parameters for PointToPoint links and channels
  Config::SetDefault("ns3::PointToPointNetDevice::DataRate", StringValue("1Mbps"));
  Config::SetDefault("ns3::PointToPointChannel::Delay", StringValue("10ms"));
  Config::SetDefault("ns3::QueueBase::MaxPackets", UintegerValue(20));

  // Read optional command-line parameters (e.g., enable visualizer with ./waf --run=<> --visualize
  CommandLine cmd;
  cmd.Parse(argc, argv);

  // Creating nodes
  NodeContainer nodes;
  nodes.Create(3);

  // Connecting nodes using two links
  PointToPointHelper p2p;
  p2p.Install(nodes.Get(0), nodes.Get(1));
  p2p.Install(nodes.Get(1), nodes.Get(2));

  // Install Ndn stack on all nodes
  ndn::StackHelper ndnHelper;
  ndnHelper.SetDefaultRoutes(true);
  ndnHelper.setCsSize(2); // allow just 2 entries to be cached
  ndnHelper.setPolicy("nfd::cs::lru");
  ndnHelper.InstallAll();

  // Installing applications

  // Consumer
  ndn::AppHelper consumerHelper("OneInterestRequester");

  // /*
  //   1) at time 1 second requests Data from a producer that does not specify freshness
  //   2) at time 10 seconds requests the same Data packet as client 1

  //   3) at time 2 seconds requests Data from a producer that specifies freshness set to 2 seconds
  //   4) at time 12 seconds requests the same Data packet as client 3

  //   Expectation:
  //   Interests from 1, 3 and 4 will reach producers
  //   Interset from 2 will be served from cache
  //  */

  consumerHelper.SetPrefix("/no-freshness");
  consumerHelper.Install(nodes.Get(0)).Start(Seconds(1));
  consumerHelper.Install(nodes.Get(0)).Start(Seconds(10));

  consumerHelper.SetPrefix("/with-freshness");
  consumerHelper.Install(nodes.Get(0)).Start(Seconds(2));
  consumerHelper.Install(nodes.Get(0)).Start(Seconds(12));

  // Producer
  ndn::AppHelper producerHelper("ns3::ndn::Producer");
  producerHelper.SetAttribute("PayloadSize", StringValue("1024"));

  producerHelper.SetAttribute("Freshness", TimeValue(Years(100))); // freshness long enough
  producerHelper.SetPrefix("/no-freshness");
  producerHelper.Install(nodes.Get(2)); // last node

  producerHelper.SetAttribute("Freshness", TimeValue(Seconds(2.0))); // freshness 2 seconds (!!!
                                                                     // freshness granularity is 1
                                                                     // seconds !!!)
  producerHelper.SetPrefix("/with-freshness");
  producerHelper.Install(nodes.Get(2)); // last node

  Simulator::Stop(Seconds(30.0));

  Simulator::Run();
  Simulator::Destroy();

  return 0;
}
} // namespace ns3

int
main(int argc, char* argv[])
{
  return ns3::main(argc, argv);
}
