/* -*- 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: Wentao Shang <wentao@cs.ucla.edu>
 */


#include "face.hpp"

class Consumer
{
public:
  Consumer (const std::string &data_name, int pipe_size, int total_seg, int scope = -1, bool mustBeFresh = true)
    : m_data_name (data_name), m_pipe_size (pipe_size), m_total_seg (total_seg),
      m_next_seg (0), m_total_size (0), m_output (false)
	  , m_scope(scope)
      , m_mustBeFresh(mustBeFresh)
  {
  }

  inline void
  enable_output ()
  {
    m_output = true;
  }

  void
  run ();
  
private:
  void
  on_data (const ndn::Interest& interest, ndn::Data& data);

  void
  on_timeout (const ndn::Interest& interest);
  
  ndn::Face m_face;
  ndn::Name m_data_name;
  int m_pipe_size;
  int m_total_seg;
  int m_next_seg;
  int m_total_size;
  bool m_output;  // set to false by default

  int m_scope;
  bool m_mustBeFresh;
};

void
Consumer::run ()
{
  try
    {
      for (int i = 0; i < m_pipe_size; i++)
	{
	  ndn::Interest inst (ndn::Name(m_data_name).appendSegment (m_next_seg++));
	  inst.setInterestLifetime (4000);
	  if (m_scope >= 0)
		  inst.setScope (m_scope);
	  inst.setMustBeFresh (m_mustBeFresh);
	  
	  m_face.expressInterest (inst,
				  ndn::bind (&Consumer::on_data, this, _1, _2),
				  ndn::bind (&Consumer::on_timeout, this, _1));
	}
      
      // processEvents will block until the requested data received or timeout occurs
      m_face.processEvents ();
    }
  catch (std::exception& e)
    {
      std::cerr << "ERROR: " << e.what () << std::endl;
    }
}

void
Consumer::on_data (const ndn::Interest& interest, ndn::Data& data)
{
  const ndn::Block& content = data.getContent ();
  const ndn::Name& name = data.getName ();

  if (m_output)
    {
      std::cout.write(reinterpret_cast<const char*>(content.value()), content.value_size());
    }

  m_total_size += content.value_size ();
  
  if ((int) (name.rbegin ()->toSegment ()) + 1 == m_total_seg)
    {
      std::cerr << "Last segment received." << std::endl;
      std::cerr << "Total # bytes of content received: " << m_total_size << std::endl;
    }
  else
    {
      // Send interest for next segment
      ndn::Interest inst (ndn::Name(m_data_name).appendSegment (m_next_seg++));
	  if (m_scope >= 0)
	      inst.setScope (m_scope);
      inst.setInterestLifetime (4000);
      inst.setMustBeFresh (m_mustBeFresh);
      
      m_face.expressInterest (inst,
			      ndn::bind (&Consumer::on_data, this, _1, _2),
			      ndn::bind (&Consumer::on_timeout, this, _1));  
    }
}


void
Consumer::on_timeout (const ndn::Interest& interest)
{
  //XXX: currently no retrans
  std::cerr << "TIMEOUT: last interest sent for segment #" << (m_next_seg - 1) << std::endl;
}


int
usage(const std::string &filename)
{
  std::cerr << "Usage: \n    " << filename << " [-p pipe_size] [-c total_segment] [-o] /ndn/name\n";
  return 1;
}


int
main (int argc, char **argv)
{
  std::string name;
  int pipe_size = 1;
  int total_seg = std::numeric_limits<int>::max();
  bool output = false;

  int opt;
  while ((opt = getopt(argc, argv, "op:c:")) != -1)
    {
      switch (opt)
	{
        case 'p':
	  pipe_size = atoi (optarg);
	  if (pipe_size <= 0)
	    pipe_size = 1;
	  std::cerr << "main (): set pipe size = " << pipe_size << std::endl;
	  break;
	case 'c':
	  total_seg = atoi (optarg);
	  if (total_seg <= 0)
	    total_seg = 1;
	  std::cerr << "main (): set total seg = " << total_seg << std::endl;
	  break;
	case 'o':
	  output = true;
	  break;
        default: 
	  return usage(argv[0]);
        }
    }

  if (optind < argc)
    {
      name = argv[optind];
    }
  
  if (name.empty())
    {
      return usage(argv[0]);
    }
  
  Consumer consumer (name, pipe_size, total_seg);

  if (output)
    consumer.enable_output ();
  
  consumer.run ();

  return 0;
}
