package senseiTests.testerGMNS;

import sensei.gmns.*;
import sensei.util.*;
import sensei.middleware.gms.*;
import sensei.middleware.gmns.*;
import sensei.util.Error;

import java.io.IOException;
import java.util.Random;
import java.util.Vector;

public class Tester implements ErrorHandler
{
  public Tester(Parameters parameters)  throws ParameterException, Exception
  {
    Error.setErrorHandler(this);

    GroupMembershipNamingService service = GroupMembershipNamingServiceFactory.load();
    if (service==null)
    {
      System.out.println("GroupMembershipNamingService is not available");
      System.exit(0);
    }
    else
    {
      createGroupMembers(service);
    }
  }

  void createGroupMembers(GroupMembershipNamingService service)
  {
    //on times randomly from 0 to 5 seconds, a new member is created.
    //they will live randomly up to 60 seconds
    Random random = new Random();
    String groups[]={"Antwerpen","Bonn","Collado-Mediano","Dublin","Ludwigsburg","Madrid","Ocean City",
        "Sheffield","Stuttgart"};
    String members[]={"Keizerstraat","Manantiales","Mar de Aral","Santa Virgilia","New Road Place","AdenauerAllee",
        "SchuetzenStrasse", "VaihingenStrasse","La Bodeguita","Cirque Royal","Le Sud", "Alcatel", "IONA",
        "T-Mobil","Telefonica","CPS","UCM"};

    int groupsLength = groups.length;
    int membersLength = members.length;
    try
    {
      while(true)
      {
        int randomGroup = random.nextInt(groupsLength);
        int randomMember = random.nextInt(membersLength);
        int randomLive = random.nextInt(MAX_LIFE);
        int randomSleep = random.nextInt(MAX_SLEEP);

        String group = groups[randomGroup];
        String name = members[randomMember];

        joinMember(service, group, name, randomLive);

        Thread.sleep(randomSleep*1000);
      }
    }
    catch(Exception ex)
    {
      Error.unhandledException("",ex);
    }
  }

  void joinMember(GroupMembershipNamingService service, String group, String name, int live) throws Exception
  {
    GroupMember member = new TestGroupMember(group, name, live).theGroupMember();
    GroupHandlerFactory ghFactory=new GroupHandlerFactoryImpl(member).theGroupHandlerFactory();
    service.findAndJoinGroup(group, ghFactory, name, null);
  }


  //*************************************************************************************
  //**************************** ERRORS *************************************************
  //*************************************************************************************

  public boolean handleError(String area, String reason)
  {
    System.out.println("ERROR on "+area+": " + reason);
    return false;
  }

  public boolean handleException(String area, Exception exception)
  {
    exception.printStackTrace();
    return handleError(area,exception.toString());
  }

  //*************************************************************************************
  //**************************** READ ARGS **********************************************
  //*************************************************************************************

  /**
    * Reads the command line arguments, and initializes the
    * Configuration singleton class; arguments are translated into the Parameter class and
    * returned.
    * It returns null if arguments are incorrect or they do not require any GMNS processing
    **/
  public static Parameters readArgs(String args[])
  {
    Parameters ret = null;
    try
    {
      Vector params=new Vector();
      params.add(CONF);
      params.add(HELP);

      ret = new Parameters(args, params, null,0,0);
      if (ret.hasParameter(HELP))
        help();
      else
      {
        if (ret.hasParameter(CONF))
          Configuration.getSingleton(ret.getParameter(CONF), ret.getDefinitions());
        else
          Configuration.getSingleton(ret.getDefinitions());
      }
    }
    catch (ParameterException pex)
    {
      System.err.println("Arguments error: " + pex.getMessage());
      help();
    }
    catch (IOException ioex)
    {
      System.err.println("Error reading the configuration file: " + ioex.getMessage());
    }
    return ret;
  }

  //*************************************************************************************
  //**************************** HELP ***************************************************
  //*************************************************************************************

  static void help()
  {
      System.out.println("arguments: [options...]\n\tOptions:\n\t\t"
        + CONF + "=configuration file\n\t\t\t--> sensei properties file \n\t\t"
        + HELP + "\n\t\t\t--> shows this brief help \n\n\t"
      );
  }

  //*************************************************************************************
  //**************************** DATA MEMBERS *******************************************
  //*************************************************************************************

  static final String CONF      = "config";
  static final String HELP      = "help";

  static final int MAX_LIFE = 20;
  static final int MAX_SLEEP = 5;
}