import ilog.rules.factory.*;
import ilog.rules.inset.*;
import java.util.*;
import ruleflow.*;
import junit.framework.*;

ruleset execution
{
  property ilog.rules.engine.localVariablePrecedence = false;
   in int testint;
   inout ArrayList list;
   int intParam;
   boolean boolParam;
   String stringParam = "first loop";
   
   boolean finalactionmain=false;
}

/**This task is the main task*/
flowtask main
{
  property testProperty = "this is a property test";
  initialaction {
    /*     System.out.println("main initialaction" +
			" intParam = " + intParam +
			" boolParam = " + boolParam +
			" stringParam = " + stringParam);*/
     bind task = ?context.getTask("main");
     bind pptylist = task.getProperties();
     if (pptylist.containsKey("testProperty"))
	{
	bind entry = pptylist.get("testProperty");	
	//        System.out.println("testProperty = " + entry.getValue());
	}
     bind taskEngine = ?context.getTaskEngine();
     bind comment = task.getFormalComment();
     Assert.assertEquals("Wrong value for comment string",
			 "This task is the main task", comment);
  }
  finalaction {
    /*     System.out.println("main finalaction" +
			" intParam = " + intParam +
			" boolParam = " + boolParam +
			" stringParam = " + stringParam);*/
	finalactionmain = true;
  }
  body {
    ruletask1;
    if1: if (intParam > 2)
      functiontask1;
    else
    {
	ruletask2;
	functiontask2;
    }
    flow1;
    while(boolParam)
    {
	ruletask3;
	if (intParam+2 > 7 && intParam < 10)
	  continue;
	else
	  if (intParam <= 3)
	    {
    		switch(intParam)
    		{
		  case 1:
	  	   functiontask1;
		  case 2:
		  {
	  	   if (!boolParam)
	   	   {
	     	     functiontask2;
	     	     functiontask3;
	   	   }
	  	   else
	   	   {
	     	    functiontask4;
	     	    functiontask5;
	   	   }
	          }
	          default:
	     	    functiontask5;
	      	}
		if (intParam > 3)
	      	  break;    
	    }
    }
    fk1 : fork {
      ruletask4;
      ruletask3;
    }
    &&
    {
      functiontask3;
    }
    if (stringParam.equals("first loop"))
     goto if1;
  }
}

rule rule1
{
   when {
     not Integer();
   }
   then {
     //     System.out.println("rule rule1");
     assert(new Integer(3));
     intParam = 1;
   }
}

rule rule2
{
  when {
   ?i: Integer();
  }
  then {
    //	System.out.println("rule rule2");
  }
}

rule rule3
{
  when {
   ?i: Integer();
  }
  then {
    //     System.out.println("rule rule3");
  }
}

rule rule4
{
  when {
   ?i: Float();
  }
  then {
    if (intParam > 3)
       boolParam = false;
    intParam += 1;
    //    System.out.println("rule rule4 intParam = " + intParam);
  }
}

ruletask ruletask1
{
  algorithm = default;
  initialaction {
    /*     System.out.println("ruletask1 initialaction" +
			" intParam = " + intParam +
			" boolParam = " + boolParam +
			" stringParam = " + stringParam);*/
	bind task = (IlrRuleTask)?context.getTask("ruletask1");
	bind algo = task.getAlgorithm();
	
	Assert.assertEquals("Error: algorithm != default",
			    IlrRulesetConstants.DefaultAlgorithm, algo);
  }
  finalaction {
    /*     System.out.println("ruletask1 finalaction" +
			" intParam = " + intParam +
			" boolParam = " + boolParam +
			" stringParam = " + stringParam);*/
  }
  body = select(?rule) { return true; }
}

ruletask ruletask2
{
  initialaction {
    /*     System.out.println("ruletask2 initialaction" +
			" intParam = " + intParam +
			" boolParam = " + boolParam +
			" stringParam = " + stringParam);*/
  }
  finalaction {
    /*     System.out.println("ruletask2 finalaction" +
			" intParam = " + intParam +
			" boolParam = " + boolParam +
			" stringParam = " + stringParam);*/
  }
  body {
    rule1, rule2, rule3
  }
}
ruletask ruletask3
{
  algorithm = sequential;
  ordering = sorted;
  initialaction {
    /*     System.out.println("ruletask3 initialaction" +
			" intParam = " + intParam +
			" boolParam = " + boolParam +
			" stringParam = " + stringParam);*/
	bind task = (IlrRuleTask)?context.getTask("ruletask3");
	bind algo = task.getAlgorithm();
	Assert.assertEquals("Error: algorithm != sequential",
			    IlrRulesetConstants.SequentialAlgorithm, algo);
  }
  finalaction {
    /*     System.out.println("ruletask3 finalaction" +
			" intParam = " + intParam +
			" boolParam = " + boolParam +
			" stringParam = " + stringParam);*/
  }
  body {
     rule4
  }
}
ruletask ruletask4
{
  initialaction {
    /*     System.out.println("ruletask4 initialaction" +
			" intParam = " + intParam +
			" boolParam = " + boolParam +
			" stringParam = " + stringParam);*/
  }
  finalaction {
    /*     System.out.println("ruletask4 finalaction" +
			" intParam = " + intParam +
			" boolParam = " + boolParam +
			" stringParam = " + stringParam);*/
  }
  body = select(?rule) {
	bind name = ?rule.getName();
	bind substr = "5";
	if (name.indexOf(substr) != -1)
	  return true;
	else
	  return false;
  }
}
functiontask functiontask1
{
  initialaction {
    /*     System.out.println("functiontask1 initialaction" +
			" intParam = " + intParam +
			" boolParam = " + boolParam +
			" stringParam = " + stringParam);*/
  }
  finalaction {
    /*     System.out.println("functiontask1 finalaction" +
			" intParam = " + intParam +
			" boolParam = " + boolParam +
			" stringParam = " + stringParam);*/
  }
  body {
    //     System.out.println("functiontask1 body");
     stringParam = "other loop";
  }
}
functiontask functiontask2
{
  initialaction {
    /*     System.out.println("functiontask2 initialaction" +
			" intParam = " + intParam +
			" boolParam = " + boolParam +
			" stringParam = " + stringParam);*/
  }
  finalaction {
    /*     System.out.println("functiontask2 finalaction" +
			" intParam = " + intParam +
			" boolParam = " + boolParam +
			" stringParam = " + stringParam);*/
  }
  body {     
    //     System.out.println("functiontask2 body");
     boolParam = true;
     assert(new Float(3.4));
  }
}
functiontask functiontask3
{
  initialaction {
    /*     System.out.println("functiontask3 initialaction" +
			" intParam = " + intParam +
			" boolParam = " + boolParam +
			" stringParam = " + stringParam);*/
     bind taskEngine = ?context.getTaskEngine();
/*     bind currentWItem = taskEngine.getCurrentItem();
     bind itemNode = currentWItem.getNode();
     if (!(itemNode instanceof IlrExecTaskInstance))
      System.out.println("Error: work item during execution of functiontask3 "
	 		+ "is not an IlrExecTaskInstance: "
			+ itemNode.getClass().getName());*/
  }
  finalaction {
    /*     System.out.println("functiontask3 finalaction" +
			" intParam = " + intParam +
			" boolParam = " + boolParam +
			" stringParam = " + stringParam);*/
  }
  body {     
    //     System.out.println("functiontask3 body");
     intParam = 4;
  }
}
functiontask functiontask4
{
  initialaction {
    /*     System.out.println("functiontask4 initialaction" +
			" intParam = " + intParam +
			" boolParam = " + boolParam +
			" stringParam = " + stringParam);*/
  }
  finalaction {
    /*     System.out.println("functiontask4 finalaction" +
			" intParam = " + intParam +
			" boolParam = " + boolParam +
			" stringParam = " + stringParam);*/
  }
  body {
    //     System.out.println("functiontask4 body");
  }
}
functiontask functiontask5
{
  initialaction {
    /*     System.out.println("functiontask5 initialaction" +
			" intParam = " + intParam +
			" boolParam = " + boolParam +
			" stringParam = " + stringParam);*/
  }
  finalaction {
    /*     System.out.println("functiontask5 finalaction" +
			" intParam = " + intParam +
			" boolParam = " + boolParam +
			" stringParam = " + stringParam);*/
  }
  body {
    //     System.out.println("functiontask5 body");
  }
  completionflag = completionflag();
}

flowtask flow1
{
  initialaction {
    /*     System.out.println("flow1 initialaction" +
			" intParam = " + intParam +
			" boolParam = " + boolParam +
			" stringParam = " + stringParam);*/
  }
  finalaction {
    /*     System.out.println("flow1 finalaction" +
			" intParam = " + intParam +
			" boolParam = " + boolParam +
			" stringParam = " + stringParam);*/
  }
  body {
    functiontask5;
    functiontask4;
  }
}

function boolean completionflag()
{
   if (intParam == 1)
     {
       intParam += 1;
       return false;
   }
   else
     return true; 
}

function void ilrmain(Object ?arg)
{
  //  ?context.setTaskEngineTraceLevel(3);
  bind exceptionHandler = new MyExceptionHandler();
  ?context.setRuleflowExceptionHandler(exceptionHandler);  
  bind mT= ?context.getMainTask();

  Assert.assertNotNull("Error: the mainTask should not be null", mT);
  Assert.assertEquals("Error: the main should be main", "main", mT.getName());

  ?context.execute();

  // ******************** Resume execution ****************
  bind map = ?context.execute();
  bind nrules = map.getIntValue("ilog.rules.firedRulesCount");
  Assert.assertEquals("Error: wrong number of fired rules", 10, nrules);

  Assert.assertEquals("Error: wrong value for intParam", 4, intParam);
  Assert.assertFalse("Error: wrong value for boolParam", boolParam);
  Assert.assertEquals("Error: wrong value for stringParam",
		      "other loop", stringParam);
  Assert.assertTrue("Error: not passed in main finalactions", finalactionmain);

//   ?context.setMainTask("unknown task");

}
