// src/testsuite/test-python_loader.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 PythonPolicyManager
 * class and its closely related cousins. More documentation to be written
 * here, thanks very much. */

#include "../python_cpu_policy_manager.hh"
#include "../python_cpu_policy.hh"

#include <sgpemv2/simulation.hh>
#include <sgpemv2/global_preferences.hh>
#include <sgpemv2/cpu_policies_gatekeeper.hh>
#include <sgpemv2/simulation.hh>
#include <sgpemv2/scheduler.hh>
#include <sgpemv2/user_interrupt_exception.hh>

#include <Python.h>
#include <glibmm/module.h>

#include <cassert>
#include <iostream>
#include <string>

using namespace sgpem;
using namespace std;

static CPUPolicy*
find_pol_by_name(const vector<CPUPolicy*>& pols, const Glib::ustring& name)
{
  vector<CPUPolicy*>::const_iterator it = pols.begin();
  for ( ; it != pols.end(); it++)
    if ((*it)->get_name() == name)
      return *it;
  return NULL;
}


int
main(int argc, char** argv)
{
  int successes = 0;

  if (argc != 2)
  {
    std::cout << "[EE] Usage:\n\t" << argv[0] <<
    " path/to/uninstalled/test/policies" << std::endl;
    exit(-1);
  }
  else
    // Add argv[1] as the directory to search for uninstalled policies
    sgpem::GlobalPreferences::get_instance().add_policies_dir(argv[1]);

  // Self-register itself to PoliciesGatekeeper, however we don't care about it
  PythonCPUPolicyManager polman;

  Simulation& sim = Simulation::get_instance();
  History&    his = sim.get_history();
  CPUPoliciesGatekeeper& pgk = CPUPoliciesGatekeeper::get_instance();

  const std::vector<CPUPolicy*>& policies = polman.get_avail_policies();

  // Print out avail policies
  cout << "These are the policies I found:" << endl;
  vector<CPUPolicy*>::const_iterator it = policies.begin();
  for (; it != policies.end(); it++)
    cout << "\t * " << (*it)->get_name() << endl;

  try
  {
    CPUPolicy* pol = find_pol_by_name(policies, "python_loader_configure");
    assert(pol != NULL);

    // activate_policy will also configure the policy
    pgk.activate_policy(&his, pol);
  }
  catch (UserInterruptException e)
  {
    cout << "configure: Caught UserInterruptException" << endl;
    successes++;
  }


  try
  {
    CPUPolicy* pol = find_pol_by_name(policies, "python_loader_is_preemptive");
    assert(pol != NULL);
    pgk.activate_policy(&his, pol);
    pol->is_pre_emptive();
  }
  catch (UserInterruptException e)
  {
    cout << "is_preemptive: Caught UserInterruptException" << endl;
    successes++;
  }


  try
  {
    CPUPolicy* pol = find_pol_by_name(policies, "python_loader_get_time_slice");
    assert(pol != NULL);
    pgk.activate_policy(&his, pol);
    pol->get_time_slice();
  }
  catch (UserInterruptException e)
  {
    cout << "get_time_slice: Caught UserInterruptException" << endl;
    successes++;
  }



  try
  {
    CPUPolicy* pol = find_pol_by_name(policies, "python_loader_get_time_slice");
    assert(pol != NULL);
    pgk.activate_policy(&his, pol);
    pol->sort_queue();
  }
  catch (UserInterruptException e)
  {
    cout << "sort_queue: Caught UserInterruptException" << endl;
    successes++;
  }

  cout << "Result: catched " << successes
  << " exceptions out of 4." << endl;

  exit(0);
}
