///////////////////////////////////////////////////////////////////////////////
//
// 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
///////////////////////////////////////////////////////////////////////////////
//  File:               IOT_App_Functions.ttcn
//  Description:
//  Rev:                <RnXnn>
//  Prodnr:             CNL 113 909
//  Updated:            2020-02-06
//  Contact:            http://ttcn.ericsson.se
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////
//  Module: IOT_App_Functions
// 
//  Purpose:
//    This module contains the functions of RIoT's main component
//
//  See also:
//    <IOT_App_Definitions>
//
//  Module depends on:
//    - <IOT_LGen_Definitions>
//    - <IOT_LGen_Functions>
//    - <EPTF_CLL_Base_Functions>
//    - <EPTF_CLL_ExecCtrl_Definitions>
//    - <EPTF_CLL_ExecCtrl_Functions>
//    - <EPTF_CLL_DsRestAPI_Functions>
//    - <EPTF_CLL_DataSource_Definitions>
//    - <EPTF_CLL_DataSource_Functions>
// 
//  Module Parameters:
//    tsp_nrOfLGens - <tsp_nrOfLGens> - *integer* - the number of <IOT_LGen_CT> instances to be createed during start up
//    tsp_LGname_prefix - <tsp_LGname_prefix> - *charstring* - name prefix used for the created <IOT_LGen_CT> instances
///////////////////////////////////////////////////////////////
module IOT_App_Functions 
{
  import from IOT_App_Definitions all;
  import from IOT_LGen_Definitions all;
  import from IOT_LGen_Functions all;
  import from EPTF_CLL_Base_Functions all;
  import from EPTF_CLL_ExecCtrl_Definitions all;
  import from EPTF_CLL_ExecCtrl_Functions all;
  import from EPTF_CLL_DsRestAPI_Functions all;
  
  import from EPTF_CLL_DataSource_Definitions all;
  import from EPTF_CLL_DataSource_Functions all;

  modulepar integer     tsp_nrOfLGens := 0;
  modulepar charstring  tsp_LGname_prefix := "IOT_LGen";

  ///////////////////////////////////////////////////////////
  //  Testcase: TC
  //
  //  Purpose:
  //    The main entry point of the RIoT application
  //
  //  Related Types:
  //    <IOT_App_CT>
  ///////////////////////////////////////////////////////////
  testcase TC() runs on IOT_App_CT
  {
    log(%definitionId,": Creating UI");
    f_EPTF_DsRestAPI_init_CT("IOT_App");

    log(%definitionId,": Creating ExecCtrl");
    var EPTF_ExecCtrl_CT vc_ExtCtrl := EPTF_ExecCtrl_CT.create;
    vc_ExtCtrl.start(f_IOT_App_startExecCtrl("ExecCtrl", tsp_nrOfLGens, self));

    f_EPTF_DataSource_registerReadyCallback(refers(f_EPTF_ExecCtrl_Test_DataSourceClientReady));

    log(%definitionId,": Creating LGens");
    var IOT_LGen_CT vc_LG;
    for (var integer i:=0; i<tsp_nrOfLGens; i:=i+1)
    {
      vc_LG := IOT_LGen_CT.create;
      vc_LG.start(f_IOT_LGen_behavior(tsp_LGname_prefix & int2str(i), i, vc_ExtCtrl));
    }
    
    timer T_guard, T_alt;
    T_alt.start( 0.0 );
    T_guard.start( 15.0 );
    // wait until ExecCtrl DataSource is registered
    alt{
      [] T_guard.timeout{
        setverdict(fail,"Timeout during config");
        f_EPTF_Base_stopAll();
      }
      [v_ready] T_alt.timeout{}
    }

    var integer vl_Ret := f_EPTF_DsRestAPI_start(
      tsp_EPTF_DsRestAPI_HTTPServer_RemoteAddress, 
      tsp_EPTF_DsRestAPI_HTTPServer_RemotePort, 
      tsp_EPTF_DsRestAPI_HTTPServer_directory, 
      tsp_EPTF_DsRestAPI_customizableApp_directory, 
      tsp_EPTF_DsRestAPI_API_directory
    );
    
    f_EPTF_Base_wait4Shutdown();
  }

  ///////////////////////////////////////////////////////////
  //  Function: f_IOT_App_startExecCtrl
  //
  //  Purpose:
  //    Starting up the Execution Control component that will orchestrate
  //    the load generator <IOT_LGen_CT>,<EPTF_ExecCtrlClient_CT> component instances
  //
  //  Parameters:
  //    pl_selfName - *in charstring* - name of the execution control components instance
  //    pl_nrOfClients - *in integer* - number of <EPTF_ExecCtrlClient_CT> load generator components to wait for
  //    pl_datasource - *in* <EPTF_DataSource_CT> - data source server
  //
  //  Related Types:
  //    <EPTF_ExecCtrl_CT>
  //
  //  Related functions:
  //    - <f_EPTF_ExecCtrl_loadConfig>
  //    - <f_EPTF_ExecCtrl_init_CT>
  ///////////////////////////////////////////////////////////
  function f_IOT_App_startExecCtrl(
    in charstring pl_selfName, 
    in integer pl_nrOfClients,
    in EPTF_DataSource_CT pl_datasource)
  runs on EPTF_ExecCtrl_CT
  {
    var EPTF_ExecCtrl_LGenFunction_Entry_List vl_functions :=
    {
      { name := "RIoT.createLGen", fn  := refers(f_IOT_LGen_create) }
    }

    f_EPTF_ExecCtrl_loadConfig(
      pl_EPTF_ExecCtrl_LGenFunction_Entry_List := vl_functions
    );
    
    f_EPTF_ExecCtrl_init_CT(pl_selfName, pl_nrOfClients, pl_dataSource_compRef := pl_datasource);
    
    f_EPTF_Base_wait4Shutdown();
  }

  ///////////////////////////////////////////////////////////
  //  Function: f_IOT_LGen_create
  //
  //  Purpose:
  //    Starting up a load generator <IOT_LGen_CT> component instances
  //
  //  Parameters:
  //    pl_hostname - *in charstring* - name of the host, where the load generator instance will be created
  //    pl_componentName - *in charstring* - the name of the load generator component instance
  //
  //  Related Types:
  //    <IOT_LGen_CT>
  //    <EPTF_ExecCtrlClient_CT>
  //    <EPTF_ExecCtrl_CT>
  //
  //  Related functions:
  //    - <f_IOT_LGen_behavior>
  ///////////////////////////////////////////////////////////
  function f_IOT_LGen_create
  (
    in charstring pl_hostname,
    in charstring pl_componentName  
  )
  runs on EPTF_ExecCtrl_CT
  return EPTF_ExecCtrlClient_CT
  {
    // Create LGen instance
    var IOT_LGen_CT vc_lgen := IOT_LGen_CT.create(pl_hostname);

    // Connect and Start the LGen
    vc_lgen.start(f_IOT_LGen_behavior(tsp_LGname_prefix & pl_componentName, 0, self));

    return vc_lgen;
  }
  
  function f_EPTF_ExecCtrl_Test_DataSourceClientReady(
    in charstring pl_source,
    in charstring pl_ptcName)
  runs on IOT_App_CT
  {
    if (pl_source==c_ExecCtrl_DataSource_sourceId)
    {
      v_ready := true;
    }
  }
}
