// src/testsuite/test-history.cc - Copyright 2005, 2006, University
//               of Padova, dept. of Pure and Applied
//               Mathematics
//
// This file is part of SGPEMv2.
//
// This 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 2 of the License, or
// (at your option) any later version.
//
// SGPEMv2 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 SGPEMv2; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

/* This executable tests for workingness of the SimulationWidget class,
 * and nothing else. */

#include "config.h"
#include "gettext.h"

#include <glibmm/main.h>
#include <glibmm/module.h>
#include <glibmm/ustring.h>
#include <glibmm/thread.h>
#include <gtkmm/box.h>
#include <gtkmm/button.h>
#include <gtkmm/checkbutton.h>
#include <gtkmm/main.h>
#include <gtkmm/radiobutton.h>
#include <gtkmm/scrolledwindow.h>
#include <gtkmm/window.h>

#include <cassert>
#include <iostream>

#include <sgpemv2/cpu_policies_gatekeeper.hh>
#include <sgpemv2/cpu_policy.hh>
#include <sgpemv2/cpu_policy_manager.hh>
#include <sgpemv2/resource_policies_gatekeeper.hh>
#include <sgpemv2/resource_policy.hh>
#include <sgpemv2/resource_policy_manager.hh>

#include <sgpemv2/history_observer.hh>
#include <sgpemv2/scheduler.hh>
#include <sgpemv2/simulation.hh>
#include <sgpemv2/simulation_observer.hh>
#include <sgpemv2/process.hh>
#include <sgpemv2/resource.hh>
#include <sgpemv2/thread.hh>
#include "cairo_elements.hh"
#include "cairo_widget.hh"
#include "holt_container_window.hh"
#include "holt_widget.hh"
#include "simulation_widget.hh"

using namespace sgpem;
using namespace std;
using Glib::ustring;



// ------------------------------------------------------
//
// PRRPolicy class
//
// ------------------------------------------------------
/** An hard-coded Priority Round Robin policy
  * it adds a new constructor taking the quantum size (time slice)*/

class PRRPolicy : public CPUPolicy
{
public:

  PRRPolicy()
  {
    _instance = this;
  }

  PRRPolicy(int quantum) : _quantum(quantum)
  {
    _instance = this;
  }

  static PRRPolicy& get_instance()
  {
    if (!_instance) _instance = new PRRPolicy(3); // quantum size
    return *_instance;
  }

  virtual ~PRRPolicy()
  {}

  virtual void configure() throw(UserInterruptException, MalformedPolicyException)
  {}

  virtual void sort_queue() const throw(UserInterruptException)
  { // here a lot of fun, exactly O(n^2) fun!

    // ReadyQueue sl = History.get_instance().get_simulation_status_at(get_current_time());
    ReadyQueue* sl = Scheduler::get_instance().get_ready_queue();
    if(sl && sl->size()>=2)
    {
      for (int i = 0; i < sl->size(); i++)
      {
        for (int j = 0; j < sl->size() - 1; j++)
        {
          if ( (sl->get_item_at(j).get_current_priority() < sl->get_item_at(j + 1).get_current_priority())
            || ((sl->get_item_at(j).get_current_priority() == sl->get_item_at(j + 1).get_current_priority())
                && (sl->get_item_at(j).get_last_acquisition() > sl->get_item_at(j + 1).get_last_acquisition())) )
          {
            sl->swap(j, j + 1);
          }
        }

      }
    }
  }

  /*
  int get_id() const
  {
    return 42;
  }
  */

  virtual Glib::ustring get_description() const
  {
    return "42";
  }
  virtual Glib::ustring get_name() const
  {
    return "FourtyTwo";
  }
  virtual bool is_pre_emptive() const throw(UserInterruptException, MalformedPolicyException)
  {
    return true;
  }
  virtual int get_time_slice() const throw(UserInterruptException, MalformedPolicyException)
  {
    return _quantum;
  }

  PolicyParameters& get_parameters()
  {
    return _parameters;
  }

  virtual void activate() throw(UserInterruptException, MalformedPolicyException)
  {
  }

  virtual void deactivate()
  {
  }

protected:

  PolicyParameters _parameters;
  // int _id;
  int _quantum;
private:

  static PRRPolicy* _instance;
};

PRRPolicy* PRRPolicy::_instance=0;



// ------------------------------------------------------
//
// DummyPolicyManager class
//
// ------------------------------------------------------

class DummyPolicyManager : public CPUPolicyManager
{
public:
  /** \brief CPUPolicyManager constructor
    *
  * Saves ``this'' pointer into the _registered attribute, so it can access
  * it when requested. This is done so that concrete subclasses can be defined
  * even if they are found in external dynamic modules not known at compile time.
  *
  * For the moment, just an instance of CPUPolicyManager can be saved. This will
  * be expanded in next milestones.
  */
  DummyPolicyManager()
  {
    _policies.push_back(new PRRPolicy);
  }

  virtual ~DummyPolicyManager()
  {
  }

  /**
    Gets THE policy (the only today) used.
    Next versions will implement some other kind.
    \return A reference to the policy.
    FIXME deprecated
    */
  //virtual CPUPolicy&  get_policy() = 0;

  /**
    Init (or reset if yet initialized) the manager.
    FIXME deprecated
    */
  virtual void  init()
  {
  }

  virtual const std::vector<CPUPolicy*>& get_avail_policies()
  {
    return _policies;
  }
protected:
  virtual void collect_policies()
  {
  }

};











// ------------------------------------------------------
//
// MainWindow class
//
// contains and controls the tested widget
//
// ------------------------------------------------------
class MainWindow : public Gtk::Window
{
public:
  MainWindow(Simulation& simulation);
  virtual ~MainWindow();

protected:
  virtual void on_button_start_clicked();
  virtual void on_button_stop_clicked();
  virtual void on_button_pause_clicked();
  virtual void on_button_runmode_clicked();
  virtual void on_button_showthreads_clicked();
  virtual void on_buttons_radio_clicked();
  virtual void on_buttons_radio_disp_clicked();
  virtual bool on_timer_timeout();

  // TestWidget  _test_widget;
  SimulationWidget    _simulation_widget;
  HoltWidget          _holt_widget;
  Gtk::Button         _start_button;
  Gtk::Button         _stop_button;
  Gtk::Button         _pause_button;
  Gtk::CheckButton    _runmode_button;
  Gtk::CheckButton    _showthreads_button;
  Gtk::RadioButton    _noscale_radio;
  Gtk::RadioButton    _fit_radio;
  Gtk::RadioButton    _stretch_radio;
  
  Gtk::RadioButton    _horizontal_radio;
  Gtk::RadioButton    _vertical_radio;
  Gtk::RadioButton    _circular_radio;

  Gtk::HBox           _buttons_box;
  Gtk::HBox           _buttons2_box;
  Gtk::VBox           _main_box;
  Gtk::ScrolledWindow _simulation_scroller;
  Gtk::ScrolledWindow _holt_scroller;
  Simulation::state   _sim_state;

  HoltContainerWindow _holt_container;
};


MainWindow::MainWindow(Simulation& simulation)
: _start_button("Start"),
  _stop_button("Stop"),
  _pause_button("Pause"),
  _runmode_button("Continue"),
  _showthreads_button("Show threads"),
  _noscale_radio("no scale"),
  _fit_radio("scale all"),
  _stretch_radio("stretch"),
  _horizontal_radio("dispose horizontal"),
  _vertical_radio("dispose vertical"),
  _circular_radio("dispose circular"),
  _simulation_widget(simulation),
  _holt_widget(simulation),
  _sim_state(Simulation::state_stopped),
  _holt_container(simulation)
{
  // This just sets the title of our new window.
  set_title("Holt Graph Widget Test");
  add(_main_box);
  _buttons_box.pack_start(_start_button);
  _start_button.show();
  _buttons_box.pack_start(_stop_button);
  _stop_button.show();
  _buttons_box.pack_start(_pause_button);
  _pause_button.show();
  _buttons_box.pack_start(_runmode_button);
  _runmode_button.set_active(false);
  _runmode_button.show();

  _buttons_box.pack_start(_showthreads_button);
  _showthreads_button.set_active(false);
  _showthreads_button.show();
  
  // scale radio buttons
  Gtk::RadioButton::Group group = _noscale_radio.get_group();
  _fit_radio.set_group(group);
  _stretch_radio.set_group(group);

  _buttons_box.pack_start(_noscale_radio);
  _noscale_radio.set_active();
  _noscale_radio.show();
  _buttons_box.pack_start(_fit_radio);
  _fit_radio.show();
  _buttons_box.pack_start(_stretch_radio);
  _stretch_radio.show();

  _main_box.pack_start(_buttons_box, Gtk::PACK_SHRINK);
  _buttons_box.show();

  _simulation_scroller.add(_simulation_widget);
  _simulation_widget.show();
  _simulation_scroller.show();
  _main_box.pack_start(_simulation_scroller);

  // dispose radio buttons
  Gtk::RadioButton::Group group2 = _horizontal_radio.get_group();
  _vertical_radio.set_group(group2);
  _circular_radio.set_group(group2);

  _buttons2_box.pack_start(_horizontal_radio);
  _horizontal_radio.set_active();
  _horizontal_radio.show();
  _buttons2_box.pack_start(_vertical_radio);
  _vertical_radio.show();
  _buttons2_box.pack_start(_circular_radio);
  _circular_radio.show();

  _main_box.pack_start(_buttons2_box, Gtk::PACK_SHRINK);
  _buttons2_box.show();

  _holt_scroller.add(_holt_widget);
  _holt_widget.show();
  _holt_scroller.show();
  _main_box.pack_start(_holt_scroller);

  _main_box.show();
  
  // connect after standard signal handler
  _start_button.signal_clicked().connect( sigc::mem_fun(*this, &MainWindow::on_button_start_clicked), true );
  _stop_button.signal_clicked().connect( sigc::mem_fun(*this, &MainWindow::on_button_stop_clicked), true );
  _pause_button.signal_clicked().connect( sigc::mem_fun(*this, &MainWindow::on_button_pause_clicked), true );
  _runmode_button.signal_clicked().connect( sigc::mem_fun(*this, &MainWindow::on_button_runmode_clicked), true );
  _showthreads_button.signal_clicked().connect( sigc::mem_fun(*this, &MainWindow::on_button_showthreads_clicked), true );

  _noscale_radio.signal_clicked().connect( sigc::mem_fun(*this, &MainWindow::on_buttons_radio_clicked), true );
  _fit_radio.signal_clicked().connect( sigc::mem_fun(*this, &MainWindow::on_buttons_radio_clicked), true );
  _stretch_radio.signal_clicked().connect( sigc::mem_fun(*this, &MainWindow::on_buttons_radio_clicked), true );

  _horizontal_radio.signal_clicked().connect( sigc::mem_fun(*this, &MainWindow::on_buttons_radio_disp_clicked), true );
  _vertical_radio.signal_clicked().connect( sigc::mem_fun(*this, &MainWindow::on_buttons_radio_disp_clicked), true );
  _circular_radio.signal_clicked().connect( sigc::mem_fun(*this, &MainWindow::on_buttons_radio_disp_clicked), true );

  Glib::signal_timeout().connect(sigc::mem_fun(*this, &MainWindow::on_timer_timeout), 1000);

  on_button_runmode_clicked();
  on_button_showthreads_clicked();

 //is equivalent to:
 /*
 const Glib::RefPtr<Glib::TimeoutSource> timeout_source = Glib::TimeoutSource::create(1000);
 timeout_source->connect(sigc::ptr_fun(&timeout_handler));
 timeout_source->attach(Glib::MainContext::get_default());
 */
  _holt_container.set_keep_above();
  // _holt_container.set_deletable(false);
  _holt_container.show();
}

MainWindow::~MainWindow()
{
}

void MainWindow::on_button_start_clicked()
{
  std::cout << "on_button_start_clicked" << endl;
  if(_sim_state == Simulation::state_stopped
    || _sim_state == Simulation::state_paused)
  {
    if(!_runmode_button.get_active()) 
    {
      // one step - drive directly simulation
      Simulation& simu = Simulation::get_instance();
      simu.run();
      _sim_state = simu.get_state();
      // _simulation_widget.redraw();
    }
    else
    {
      _sim_state = Simulation::state_running;
    }
  }
}
void MainWindow::on_button_stop_clicked()
{
  std::cout << "on_button_stop_clicked" << endl;
  if(_sim_state == Simulation::state_running
    || _sim_state == Simulation::state_paused)
  {
    _sim_state = Simulation::state_stopped;
    Simulation::get_instance().stop();
    // _simulation_widget.redraw();
  }
}
void MainWindow::on_button_pause_clicked()
{
  std::cout << "on_button_pause_clicked" << endl;
  if(_sim_state == Simulation::state_running)
  {
    _sim_state = Simulation::state_paused;
  }
  else if(_sim_state == Simulation::state_paused)
  {
    _sim_state = Simulation::state_running;
  }
}

void MainWindow::on_button_runmode_clicked()
{
  std::cout << "on_button_runmode_clicked" << endl;
}

void MainWindow::on_button_showthreads_clicked()
{
  std::cout << "on_button_showthreads_clicked" << endl;
  _simulation_widget.set_show_threads(_showthreads_button.get_active());
  _simulation_widget.resize_redraw();
  _holt_widget.set_show_threads(_showthreads_button.get_active());
  _holt_widget.resize_redraw();
}


void MainWindow::on_buttons_radio_clicked()
{
  std::cout << "on_buttons_radio_clicked" << endl;
  if(_noscale_radio.get_active())
  {
    // std::cout << "scaling_none" << endl;
    _simulation_widget.set_scaling_mode(CairoWidget::scaling_none);
    _holt_widget.set_scaling_mode(CairoWidget::scaling_none);
  }
  else if(_fit_radio.get_active())
  {
    // std::cout << "scaling_min" << endl;
    _simulation_widget.set_scaling_mode(CairoWidget::scaling_min);
    _holt_widget.set_scaling_mode(CairoWidget::scaling_min);
  }
  else
  {
    // std::cout << "scaling_all" << endl;
    _simulation_widget.set_scaling_mode(CairoWidget::scaling_all);
    _holt_widget.set_scaling_mode(CairoWidget::scaling_all);
  }
  _simulation_widget.resize_redraw();
  _simulation_widget.set_size_request (20, 20);
  _holt_widget.resize_redraw();
  _holt_widget.set_size_request (20, 20);
}



void MainWindow::on_buttons_radio_disp_clicked()
{
  std::cout << "on_buttons_radio_disp_clicked" << endl;
  if(_horizontal_radio.get_active())
  {
    // std::cout << "_horizontal_radio" << endl;
    _holt_widget.set_arrange_mode(HoltWidget::arrange_horizontal);
  }
  else if(_vertical_radio.get_active())
  {
    // std::cout << "_vertical_radio" << endl;
    _holt_widget.set_arrange_mode(HoltWidget::arrange_vertical);
  }
  else
  {
    // std::cout << "_circular_radio" << endl;
    _holt_widget.set_arrange_mode(HoltWidget::arrange_circular);
  }
  _holt_widget.resize_redraw();
}


bool MainWindow::on_timer_timeout()
{
  // std::cout << "Timer sim stat= " << _sim_state << endl;
  if(_sim_state == Simulation::state_running)
  {
    Simulation& simu = Simulation::get_instance();
    simu.run();
    // _simulation_widget.redraw();
    if(simu.get_state()==Simulation::state_stopped)
      _sim_state = Simulation::state_stopped;
  }
  return true;
}



// utility functions...

// insert some resources, processes, threads, requests, subrequests
void fillHistory(History &hist);

// print entire environment into the passed ostream
void dumpEnvironment(const Environment& env, ostream &os);

// return the Schedulable::state readable string
Glib::ustring get_schedulable_state_name(Schedulable::state st);

// return the Request::state readable string
Glib::ustring get_request_state_name(Request::state st);

// return the Simulation::state readable string
Glib::ustring get_simulation_state_name(Simulation::state st);




// ------------------------------------------------------
//
// program main
//
// ------------------------------------------------------

int
main(int argc, char** argv)
{
  ostream& info = cout;
  ostream& test = cerr;

  Gtk::Main kit(argc, argv);

  // Set up Glib thread support
  Glib::thread_init();

  info << "test-holt - start \n";

  Simulation& simu = Simulation::get_instance();
  info << "gets simulation \n";

  History& hist = Simulation::get_instance().get_history();

  ResourcePolicyManager & rpm = *ResourcePoliciesGatekeeper::get_instance().get_registered().at(0);
  Simulation::get_instance().set_resource_policy(rpm.get_avail_policies().at(0));

  info << "gets history \n";

  DummyPolicyManager dummy_manager;

  const std::vector<CPUPolicy*>& policies =  dummy_manager.get_avail_policies();
  CPUPolicy* pol = policies[0];
  info << "policy " << pol->get_name() << endl;
  
  fillHistory(hist);
  info << "history filled \n";

  simu.set_policy(pol);
  info << "policy activated \n";

  simu.set_mode(Simulation::mode_step_by_step);
  info << "simulation set_mode single step\n";

  info << "START environment dump \n";
  dumpEnvironment(hist.get_last_environment(), info);
  info << "END environment dump \n";
  info << "simulation state: " << get_simulation_state_name(simu.get_state()) << endl;

  MainWindow win(simu);

  win.set_border_width(10);
  win.resize (900, 600);

  Gtk::Main::run(win);
  return 0;
}



// insert some resources, processes, threads, requests, subrequests
void fillHistory(History &hist)
{
  // insert resources to delete soon
  // this create a numbering of keys starting from 2...
  // serves to prove correct save/restore independent from key numbering
  // add a resource - name, preemptable, places, availability
  History::ResourcePair respair0 = hist.add_resource(Glib::ustring("Resource 0"), false, 1, 2);
  // add a resource - name, preemptable, places, availability
  History::ResourcePair respair00 = hist.add_resource(Glib::ustring("Resource 00"), false, 1, 2);

  // add a resource - name, preemptable, places, availability
  History::ResourcePair respair = hist.add_resource(Glib::ustring("Resource 1"), false, 1, 2);

  // add a resource - name, preemptable, places, availability
  History::ResourcePair respair2 = hist.add_resource(Glib::ustring("Very Long Named Resource 2"), false, 1, 2);
  
  // delete resources to kreate a key numbering hole
  // hist.remove(respair0.first);
  // hist.remove(respair00.first);

  // add a process - name, arrival time, priority
  Process&   p1 =  hist.add_process(Glib::ustring("Process 1"), 0, 2); // name, arrival time, priority

  // add a process - name, arrival time, priority
  Process&   p2 =  hist.add_process(Glib::ustring("Process 2"), 7, 3); // name, arrival time, priority

  // add a process - name, arrival time, priority
  Process&   p3 =  hist.add_process(Glib::ustring("Process 3"), 5, 5); // name, arrival time, priority

  // add a process - name, arrival time, priority
  Process&   p4 =  hist.add_process(Glib::ustring("Very Long Named Process 4"), 9, 1); // name, arrival time, priority

  // add a thread - name, parent, cpu time, arrival time, priority
  Thread&   p1_t1 =  hist.add_thread(Glib::ustring("P1 - Th 1"), p1, 14, 0, 2);

  // add a thread - name, parent, cpu time, arrival time, priority
  Thread&   p1_t2 =  hist.add_thread(Glib::ustring("P1 - Th 2"), p1, 3, 3, 5);

  // add a thread - name, parent, cpu time, arrival time, priority
  Thread&   p1_t3 =  hist.add_thread(Glib::ustring("P1 - Th 3"), p1, 4, 3, 5);

  // add a thread - name, parent, cpu time, arrival time, priority
  Thread&   p1_t4 =  hist.add_thread(Glib::ustring("P1 - Th 4"), p1, 5, 3, 4);

  // add a thread - name, parent, cpu time, arrival time, priority
  Thread&   p2_t1 =  hist.add_thread(Glib::ustring("P2 - Th 1"), p2, 20, 0, 2);

  // add a thread - name, parent, cpu time, arrival time, priority
  Thread&   p3_t1 =  hist.add_thread(Glib::ustring("P3 - Th 2"), p3, 12, 0, 2);

  // add a thread - name, parent, cpu time, arrival time, priority
  Thread&   p4_t1 =  hist.add_thread(Glib::ustring("P4 - Th 1"), p4, 7, 0, 2);

  // add a thread - name, parent, cpu time, arrival time, priority
  Thread&   p4_t2 =  hist.add_thread(Glib::ustring("P4 - Th 2"), p4, 3, 6, 2);

  // add a request - Thread, time
  Request&   req1 =  hist.add_request(p1_t1, 3);

  // add a sub request - Request, resource_key, duration, places
  SubRequest& req1_sub1 = hist.add_subrequest(req1, respair.first, 6);
  
  // add a request - Thread, time
  Request&   req2 =  hist.add_request(p2_t1, 1);

  // add a sub request - Request, resource_key, duration, places
  SubRequest& req2_sub1 = hist.add_subrequest(req2, respair.first, 4);

  // add a request - Thread, time
  Request&   req3 =  hist.add_request(p3_t1, 0);

  // add a sub request - Request, resource_key, duration, places
  SubRequest& req3_sub1 = hist.add_subrequest(req3, respair.first, 5);

  // add a request - Thread, time
  Request&   req3bis =  hist.add_request(p3_t1, 7);

  // add a sub request - Request, resource_key, duration, places
  SubRequest& req3bis_sub1 = hist.add_subrequest(req3bis, respair.first, 5);
}


Glib::ustring get_schedulable_state_name(Schedulable::state st)
{
  switch(st)
  {
    case Schedulable::state_running:
      return Glib::ustring("Schedulable::state_running");
      break;
    case Schedulable::state_ready:
      return Glib::ustring("Schedulable::state_ready");
      break;
    case Schedulable::state_blocked:
      return Glib::ustring("Schedulable::state_blocked");
      break;
    case Schedulable::state_future:
      return Glib::ustring("Schedulable::state_future");
      break;
    case Schedulable::state_terminated:
      return Glib::ustring("Schedulable::state_terminated");
      break;
  }
}

Glib::ustring get_request_state_name(Request::state st)
{
  switch(st)
  {
    case Request::state_unallocable:
      return Glib::ustring("state_unallocable");
      break;
    case Request::state_allocated:
      return Glib::ustring("state_allocated");
      break;
    case Request::state_future:
      return Glib::ustring("state_future");
      break;
    case Request::state_exhausted:
      return Glib::ustring("state_exhausted");
      break;
    case Request::state_allocable:
      return Glib::ustring("state_allocable");
      break;
  }
}


Glib::ustring get_simulation_state_name(Simulation::state st)
{
  switch(st)
  {
    case Simulation::state_running:
      return Glib::ustring("Simulation::state_running");
      break;
    case Simulation::state_paused:
      return Glib::ustring("Simulation::state_paused");
      break;
    case Simulation::state_stopped:
      return Glib::ustring("Simulation::state_stopped");
      break;
  }
}


// print entire environment into the passed ostream
void dumpEnvironment(const Environment& env, ostream &os)
{
  os << "dump environment start " << endl;

  const Environment::Resources& rvect = env.get_resources();
  typedef Environment::Resources::const_iterator res_iterator;

  res_iterator riter = rvect.begin();
  while (riter != rvect.end())
  {
    Resource* r = (*riter).second;
    os << "  resource name: " << r->get_name()
    /* << " key: " << (*riter).first */
    << " places: " << r->get_places() << endl;
    riter++;
  }

  const Environment::Processes& pvect = env.get_processes();
  typedef std::vector<Process*>::const_iterator proc_iterator;

  proc_iterator iter = pvect.begin();
  proc_iterator end = pvect.end();
  while (iter != end)
  {
    Process* p = (*iter);
    os << "  process name: " << p->get_name()
    << " arrival_time: " << p->get_arrival_time()
    << " base_priority: " << p->get_base_priority()
    << " " << get_schedulable_state_name(p->get_state())
    << endl;
    iter++;

    typedef std::vector<Thread*> Threads;
    typedef std::vector<Thread*>::const_iterator thr_iterator;
    const Threads& tvect = p->get_threads();
    thr_iterator iter1 = tvect.begin();
    thr_iterator end1  = tvect.end();
    while (iter1 != end1)
    {

      Thread* t = (*iter1);
      os << "    thread name: " << t->get_name()
      << " arrival_time: " << t->get_arrival_time()
      << " base_priority: " << t->get_base_priority()
      << " " << get_schedulable_state_name(t->get_state())
      << endl;

      typedef std::vector<Request*> Requests;
      typedef std::vector<Request*>::const_iterator req_iterator;
      const Requests& rvect = t->get_requests();
      req_iterator iter2 = rvect.begin();
      req_iterator end2  = rvect.end();
      while (iter2 != end2)
      {

        Request* r = (*iter2);
        os << "      request arrival_time: " << r->get_instant() << endl;

        typedef std::vector<SubRequest*> SubRequests;
        typedef std::vector<SubRequest*>::const_iterator subreq_iterator;
        const SubRequests& srvect = r->get_subrequests();
        subreq_iterator iter3 = srvect.begin();
        subreq_iterator end3  = srvect.end();
        while (iter3 != end3)
        {

          SubRequest* sr = (*iter3);
          os << "        sub request: " /* << " resource_key: " << sr->get_resource_key() */;

          Environment::Resources::const_iterator pos = env.get_resources().find(sr->get_resource_key());
          if (pos != env.get_resources().end())
          {
            os << " name: " << pos->second->get_name();
          }

          os << " length: " << sr->get_length()
             << " " << get_request_state_name(sr->get_state())
             << endl;

          iter3++;
        }


        iter2++;
      }

      iter1++;
    }

  }
  os << "dump environment end " << endl << endl;
}

