///////////////////////////////////////////////////////////////////////////////
//                                                                           //
// Copyright (c) 2000-2019 Ericsson Telecom AB                               //
//                                                                           //
// All rights reserved. This program and the accompanying materials          //
// are made available under the terms of the Eclipse Public License v2.0     //
// which accompanies this distribution, and is available at                  //
// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html                                 //
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////
//  Module: ExecCtrlLGenPool_Demo
// 
//  Purpose:
//    This module demonstrates the usage of LGen Pools in the ExecCtrl feature
// 
//  Module Parameters:
// 
//  Module depends on:
//    <EPTF_CLL_Base_Functions>
//    <EPTF_CLL_Base_Definitions>
//    <EPTF_CLL_LGenBase_Definitions>
//    <EPTF_CLL_LGenBase_Functions>
//    <EPTF_CLL_LGenBase_ConfigFunctions>
//    <EPTF_CLL_ExecCtrl_Definitions>
//    <EPTF_CLL_ExecCtrl_Functions>
//    <EPTF_CLL_UIHandler_Definitions>
//    <EPTF_CLL_UIHandler_WidgetFunctions>
//    <XTDP_PDU_Defs>
//    <EPTF_CLL_UIHandlerCLI_Definitions>
//    <EPTF_CLL_UIHandlerCLI_Functions>
//    <EPTF_CLL_ExecCtrlUIHandler_Definitions>
//    <EPTF_CLL_ExecCtrlUIHandler_Functions>
//    <EPTF_CLL_LoggingUI_Definitions>  
//    <EPTF_CLL_LoggingUI_Functions>  
//
//  Current Owner:
//    ethjgi
// 
//  Last Review Date:
//    2009-xx-xx
// 
// 
///////////////////////////////////////////////////////////

module ExecCtrlLGenPool_Demo
{
import from EPTF_CLL_Base_Functions all;
import from EPTF_CLL_Base_Definitions all;
import from EPTF_CLL_LGenBase_Definitions all;
import from EPTF_CLL_LGenBase_Functions all;
import from EPTF_CLL_LGenBase_ConfigFunctions all;


import from EPTF_CLL_ExecCtrl_Definitions all;
import from EPTF_CLL_ExecCtrl_Functions all;

import from EPTF_CLL_UIHandler_Definitions all;
import from EPTF_CLL_UIHandler_WidgetFunctions all;
import from EPTF_CLL_UIHandler_XULFunctions all;

import from XTDP_PDU_Defs language "ASN.1:2002" all;

import from EPTF_CLL_UIHandlerCLI_Definitions all;
import from EPTF_CLL_UIHandlerCLI_Functions all;

import from EPTF_CLL_ExecCtrlUIHandler_Definitions all;
import from EPTF_CLL_ExecCtrlUIHandler_Functions all;

import from EPTF_CLL_LoggingUI_Definitions all;  
import from EPTF_CLL_LoggingUI_Functions all;  


type component LGenDemo_CT extends EPTF_LGenBase_CT, EPTF_ExecCtrlClient_UIHandler_CT
{
  var integer v_myBIdx;
}

modulepar float tsp_T_busy := 1.0; // time until entity busy

//init the "application level virtual library"
const charstring c_myVirtualAppLib_behaviorType := "LGen demo application";
const integer c_myVirtualAppLib_numberOfResources := 100;
function f_init_myVirtualAppLib() runs on LGenDemo_CT {
  var integer i;
  
  v_myBIdx:=f_EPTF_LGenBase_declareBehaviorType(c_myVirtualAppLib_behaviorType, c_myVirtualAppLib_numberOfResources, null, null, null);
  log(%definitionId,": myBIdx is ", v_myBIdx);
  
  // declare FSM (this is just a simple FSM):
  if(-1==f_EPTF_LGenBase_declareFSMTable(
  {
    name := "BasicCall",
    fsmParams := {
      {timerList := {{"busyTimer",tsp_T_busy}}},
      {stateList := {"idle", "busy"}}
    },
    table := { classicTable := {
      {eventToListen := {c_EPTF_LGenBase_behavior,c_EPTF_LGenBase_inputName_testMgmt_startTC,fsm},
        cellRow := {
          //state[0]==idle 
          {{
              {c_EPTF_LGenBase_stepName_timerStart,{timerName := "busyTimer"}}
            },omit,"busy"}
          //state[1]==busy
          ,{omit,omit,omit}
        }
      },{eventToListen := {c_EPTF_LGenBase_specialBName_timerTimeout,"busyTimer",fsm},
        cellRow := {
          //state=idle
          {omit,omit,omit}
          //state==busy
          ,{{
              {c_EPTF_LGenBase_stepName_trafficSuccess,omit}
            }, omit,"idle"}
        }
      }
    }}//table
  }
  )){};
  
}

// initialize the LGen
function f_LGen_Demo_init(in charstring pl_selfName, in EPTF_ExecCtrl_CT pl_ExecCtrlRef, in EPTF_UIHandler_CT pl_UIHandlerClient_DefaultUIHandler) runs on LGenDemo_CT {
  
  f_EPTF_LGenBase_init(pl_selfName, 0, "DemoEntity#");
  
  //initialize my FSM: 
  f_init_myVirtualAppLib() ;      //behavior type index==0 

  // my entity type is: Entity_A
  // number of entities is the same as c_myVirtualAppLib_numberOfResources
  var integer vl_eTypeIdx := f_EPTF_LGenBase_declareEntityType("Entity_A", {c_myVirtualAppLib_behaviorType});
  //log("DEBUG: v_LGenBase_entityTypes = ", v_LGenBase_entityTypes);
    
  f_EPTF_ExecCtrlClient_UIHandler_init_CT(pl_selfName,pl_ExecCtrlRef,pl_UIHandlerClient_DefaultUIHandler);
 
  //log("DEBUG: v_LGenBase_behaviorTypes = ", v_LGenBase_behaviorTypes);

  f_EPTF_LGenBase_log();

}

// This is the LGen behaviour:
function f_LGen_Demo_behavior(in charstring pl_selfName, in EPTF_ExecCtrl_CT pl_ExecCtrlRef, in EPTF_UIHandler_CT pl_UIHandlerClient_DefaultUIHandler) runs on LGenDemo_CT
{
  log(%definitionId,": started...");

  f_LGen_Demo_init(pl_selfName, pl_ExecCtrlRef,pl_UIHandlerClient_DefaultUIHandler); 

  log(%definitionId,": entering main alt-loop...")
  f_EPTF_Base_wait4Shutdown();

  f_EPTF_Base_cleanup_CT();
  log(%definitionId,": finished...");
  setverdict(pass);
}


// Prepare the GUI stuff:
function f_ExecCtrl_Demo_initGui() runs on EPTF_UIHandler_CT{

  var XTDP_XML_Tag execCtrlMainWindow := {        
      xtdp_tabpanel := {      
        id := omit,
        maxheight := omit,
        orient := "vertical",
        widgets := {
          {
            hbox := {
              id := omit,
              flex := omit,
              disabled := omit,
              orient := "horizontal",
              widgets := {
                {
                  hbox := {
                    id := omit,
                    flex := omit,
                    disabled := omit,
                    orient := "vertical",
                    widgets := {
                      { 
                        tabbox := {
                          id := c_EPTF_GUI_Main_Tabbox_WidgetId,
                          flex := omit,
                          disabled := omit,
                          layout := omit,
                          tabs := {
                          },
                          tabpanels := {
                          }
                        }
                      }
                    }
                  } 
                }              
              }
            }                      
          }
        }     
      }  
    };
      
  var boolean widgetExist := false;
  log("execCtrlMainWindow: ", execCtrlMainWindow);
  if(not f_EPTF_UIHandler_addElementToGui(
    execCtrlMainWindow, 
    "",
    widgetExist)) {
  }
}


// the main CT:
type component myMTC_CT extends EPTF_Base_CT, EPTF_UIHandler_CT, /*EPTF_ExecCtrl_UIHandler_CT,*/ EPTF_LoggingUI_CT,  EPTF_UIHandler_CLI_CT {} 

// the user ExecCtrl:
type component My_ExecCtrl_CT extends EPTF_ExecCtrl_UIHandler_CT {
  // put user variables here (e.g. v_ALL_COMPONENT_REFERENCES)
}

// Creates LGen with entity type: Entity_A
// and starts the f_LGen_Demo_behavior LGen behaviour on it
function f_myCreateLGen
(
  in charstring pl_hostname,
  in charstring pl_componentName
)
runs on My_ExecCtrl_CT
return EPTF_ExecCtrlClient_CT {
  var LGenDemo_CT LG := LGenDemo_CT.create;
  LG.start(f_LGen_Demo_behavior(pl_componentName, self, mtc));
  return LG; // LG is an LGen (i.e. it extends ExecCtrlClient_CT)
}

// always extend EPTF_Base_CT to allow cleanup to shutdown this component automatically
type component My_BuildingBlock_CT extends EPTF_Base_CT {
}

function f_My_BuildingBlock_behaviour() runs on My_BuildingBlock_CT {
  f_EPTF_Base_init_CT("My_BuildingBlock_CT");
  // Here you can do what your building block should do.
  // enter main alt-loop:
  f_EPTF_Base_wait4Shutdown();
}


// This is how the creator function should behave if the creator function does not create LGen (return null)
// This creator function can be configured to be called only on certain LGen Pools
function f_myComponentDeployment
(
  in charstring pl_hostname,
  in charstring pl_componentName
)
runs on My_ExecCtrl_CT
return EPTF_ExecCtrlClient_CT {
  // can do anything here!
  // eg. deploy your non-LGen components used by your LGenPool
  
  //Now creating only one dummy non-LGen component:
  var My_BuildingBlock_CT vl_My_BuildingBlock_CT:=My_BuildingBlock_CT.create;
  // start the behaviour function on it:
  vl_My_BuildingBlock_CT.start(f_My_BuildingBlock_behaviour());

  // here you can:
  // store the compRefs into component variable database (e.g. to v_ALL_COMPONENT_REFERENCES)
  // connect your components (e.g. in v_ALL_COMPONENT_REFERENCES)
  
  return null; // vl_My_BuildingBlock_CT is not an LGen (ExecCtrlClient_CT)
}

// the behaviour of the ExecCtrl component:
function f_My_ExecCtrl_UIHandler_behavior(
  in charstring pl_selfName, 
  in integer pl_nofLGens, 
  in EPTF_UIHandler_CT pl_uiHandler_compRef,
  in charstring pl_EPTF_GUI_Main_Tabbox_WidgetId,
  in EPTF_LoggingUI_CT pl_loggingUi_compRef := null) runs on My_ExecCtrl_CT {

  var EPTF_ExecCtrl_LGenFunction_Entry_List vl_lgenCreatorFunctions := {
    {
      omit,
      refers(f_myCreateLGen)
    },
    {
      omit,
      refers(f_myComponentDeployment)
    }
  }

  // register the creator functions (they should run on a component that extends ExecCtrl):
  f_EPTF_ExecCtrl_loadConfig(pl_EPTF_ExecCtrl_LGenFunction_Entry_List := vl_lgenCreatorFunctions);
  // initialize ExecCtrl with GUI:
  f_EPTF_ExecCtrl_UIHandler_init_CT(pl_selfName, pl_nofLGens, 
    pl_uiHandler_compRef,pl_EPTF_GUI_Main_Tabbox_WidgetId,pl_loggingUi_compRef);

  // call the basic behaviour function:
  f_EPTF_ExecCtrl_behavior(pl_selfName, pl_nofLGens);
}


testcase TC() runs on myMTC_CT
{
  log(%definitionId,": Creating UIHandler...");

  // prepare the GUI (This component is the UIHandler):
  f_EPTF_UIHandler_init_CT("ExecCtrlLGenPoolDemo_UIHandler", true); // default altsteps      
  f_EPTF_UIHandler_clearGUI();
  if(not f_EPTF_UIHandler_addWindow()) {}
  f_EPTF_UIHandler_CLI_init_CT("ExecCtrlLGenPoolDemo_UIHandler");
  f_ExecCtrl_Demo_initGui(); // create the main tabbox

  f_EPTF_LoggingUI_init_CT(
    "ExecCtrlLGenPoolDemo_UIHandler", self, c_EPTF_GUI_Main_Tabbox_WidgetId);

  // start ExecCtrl on a different PTC:
  log(%definitionId,": Creating ExecCtrl...");
  var My_ExecCtrl_CT ExtCtrl := My_ExecCtrl_CT.create;
  ExtCtrl.start(f_My_ExecCtrl_UIHandler_behavior("ExecCtrl", 0, self,c_EPTF_GUI_Main_Tabbox_WidgetId));

  // wait for exit:
  f_EPTF_Base_wait4Shutdown();
  
  //f_EPTF_Base_cleanup_CT(); // this is not necessary

  log(%definitionId,": finished")
}

control {
  execute(TC());
}

}  // end of module
