///////////////////////////////////////////////////////////////////////////////
//                                                                           //
// 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: EPTF_CLL_LoggingServer_Functions
// 
//  Purpose:
//    This module contains the implementation of generic EPTF logging functions.
// 
//  Module depends on:
//    <EPTF_CLL_Common_Definitions>
//    <EPTF_CLL_Variable_Definitions>
//    <EPTF_CLL_Logging_Definitions>
//    <EPTF_CLL_Common_Functions>
//    <EPTF_CLL_Base_Functions>
//    <EPTF_CLL_HashMapStr2Int_Functions>
//    <EPTF_CLL_DataSource_Definitions>
//    <EPTF_CLL_DataSourceClient_Functions>
//    <EPTF_CLL_Logging_Functions>
//    <EPTF_CLL_Variable_Functions>
//    <EPTF_CLL_LoggingServer_Definitions>
//    <EPTF_CLL_HashMap_Functions>

// 
//  Current Owner:
//    ELSZSKU
// 
//  Last Review Date:
//    2010-xx-xx
//
//  Detailed Comments:
//    This module contains the interface functions for the EPTF_Logging client component.
//
///////////////////////////////////////////////////////////////
module EPTF_CLL_LoggingServer_Functions
{
import from EPTF_CLL_Common_Definitions all;
import from EPTF_CLL_Variable_Definitions all;
import from EPTF_CLL_Logging_Definitions all;
import from EPTF_CLL_Common_Functions all;
import from EPTF_CLL_Base_Functions all;
import from EPTF_CLL_HashMapStr2Int_Functions all;
import from EPTF_CLL_DataSource_Definitions all;
import from EPTF_CLL_DataSourceClient_Functions all;
import from EPTF_CLL_DataSource_Functions all;
import from EPTF_CLL_Logging_Functions all;
import from EPTF_CLL_Variable_Functions all;
import from EPTF_CLL_LoggingServer_Definitions all;
import from EPTF_CLL_HashMap_Functions all;

public function f_EPTF_LoggingServer_init_CT(
  in charstring pl_selfName,
  in EPTF_DataSource_CT pl_sourceCompRef := null)
runs on EPTF_LoggingServer_CT {

  if (v_EPTF_LoggingServer_initialized) {return;}
  f_EPTF_Logging_init_CT(pl_selfName);
  var charstring vl_selfName := f_EPTF_Base_selfName();
  f_EPTF_Var_init_CT(vl_selfName);
  f_EPTF_HashMap_init_CT (vl_selfName);
  //Create DataSource variables which has no parameters, so always exist
  //Create EPTF var for global enable
  f_EPTF_Var_newBoolRef(
    c_LoggingServer_allComponentGlobalEnableVarName,
    v_EPTF_Logging_allComponentGlobalEnable,
    v_EPTF_LoggingServer_allComponentGlobalEnableIdx);
  //Create EPTF var for Selections iterator
  var EPTF_CharstringList vl_list;
  f_EPTF_Logging_getSelectionList(vl_list);
  f_EPTF_Var_newCharstringlist(
    c_LoggingServer_iteratorVarPrefix&c_LoggingServer_iteratorSelectionTypes_varName,
    vl_list,
    v_LoggingServer_iteratorSelectionsVarIdx);
  //Create EPTF var for Clients iterator without parameter
  f_EPTF_Var_newCharstringlist(
    c_LoggingServer_iteratorVarPrefix&c_LoggingServer_iteratorClients_varName,
    {},
    v_LoggingServer_iteratorClientsVarIdx);
  //Create EPTF var for ComponentTypes iterators per selection
  for ( var integer vl_i := 0,vl_size := sizeof(vl_list); vl_i < vl_size ; vl_i := vl_i+1 ){
    f_EPTF_Var_newCharstringlist(
      c_LoggingServer_iteratorVarPrefix&vl_list[vl_i]&"."&c_LoggingServer_iteratorComponentTypes_varName,
      {},
      v_LoggingServer_iteratorComponentTypesVarIdxList[vl_i]);
  }
  v_EPTF_LoggingServer_typesLookupTableID:=f_EPTF_str2int_HashMap_New (c_LoggingServer_typesLookupTable_HashName); 
  v_EPTF_LoggingServer_typesID:=0;

  f_EPTF_DataSourceClient_init_CT(vl_selfName, pl_sourceCompRef);
  f_EPTF_DataSourceClient_registerData(c_LoggingServer_sourceId, vl_selfName, refers( f_EPTF_LoggingServer_DSProcessData ), pl_sourceCompRef)
  f_EPTF_DataSourceClient_registerDataValue(c_LoggingServer_sourceId, vl_selfName, refers(f_EPTF_LoggingServer_DSProcessDataValue), pl_sourceCompRef);
  
  v_EPTF_LoggingServer_initialized := true;
  v_EPTF_LoggingServer_numberOfClients:=0;

  f_EPTF_Base_registerCleanup(refers(f_EPTF_LoggingServer_cleanup_CT));
  //log("----- LoggingServer init END -------");

  v_EPTF_LoggingServer_def:=activate(as_EPTF_LoggingServer_main_CT());
}

private altstep as_EPTF_LoggingServer_main_CT() runs on EPTF_LoggingServer_CT {

  //log("***********f_EPTF_LoggingServer_main***************");
  var EPTF_LoggingClient_CT v_send;
  var EPTF_Logging_Msg vl_req;

  [v_EPTF_LoggingServer_allowReq] EPTF_LoggingServerPort_CP.receive(tr_EPTF_Logging_req) -> value vl_req sender v_send
  {
    v_EPTF_LoggingServer_allowReq := false;
    var charstring vl_compNameList4TypeVarName := f_EPTF_LoggingServer_compNameList4TypeVarName(vl_req.Logging_Req.compType);
    var integer vl_compTypeID;
    //Store client name
    var integer vl_clientIdx := vl_req.Logging_Req.clientIdx;
    var charstring vl_clientName := f_EPTF_LoggingServer_getNameFromVar(v_LoggingServer_iteratorClientsVarIdx, vl_clientIdx);
    var integer vl_selIdx := v_LoggingServer_selIdxMap[vl_clientIdx][vl_req.Logging_Req.selectionInClient]
    //find if ID not exist
    if(not f_EPTF_str2int_HashMap_Find(v_EPTF_LoggingServer_typesLookupTableID,vl_req.Logging_Req.compType,vl_compTypeID))
    {
      v_EPTF_LoggingServer_typesID:=v_EPTF_LoggingServer_typesID+1;
      f_EPTF_str2int_HashMap_Insert(v_EPTF_LoggingServer_typesLookupTableID,vl_req.Logging_Req.compType,v_EPTF_LoggingServer_typesID);
      vl_compTypeID := v_EPTF_LoggingServer_typesID;
      //Add type to the list
      v_LoggingServer_dummyInt := f_EPTF_LoggingServer_addNewNameByIdx(v_LoggingServer_iteratorComponentTypesVarIdxList[vl_selIdx],vl_req.Logging_Req.compType);
      //Create a new EPTF Var CharstringList for the client names which registered the type
      //Initially it contains the client name from this message
      var integer vl_varId
      f_EPTF_Var_newCharstringlist(
        vl_compNameList4TypeVarName,
        {vl_clientName},
        vl_varId)
      //Create EPTF var
      f_EPTF_LoggingServer_CompTypeBindToEPTFVar(vl_req.Logging_Req.compType,v_EPTF_LoggingServer_typesID,vl_selIdx,vl_req.Logging_Req.eventClassNames);
      //Create list of classes
      f_EPTF_Var_newCharstringlist(
        f_EPTF_LoggingServer_classNameList4TypeVarName(vl_req.Logging_Req.compType),
        vl_req.Logging_Req.eventClassNames,
        vl_varId)
    }else{
      //Set client name
      f_EPTF_LoggingServer_addNewName(vl_compNameList4TypeVarName, vl_clientName);
    }
    v_EPTF_LoggingServer_allowReq := true;
    EPTF_LoggingServerPort_CP.send(c_Logging_resp) to v_send;
    repeat;
  }
  [v_EPTF_LoggingServer_allowReq] EPTF_LoggingServerPort_CP.receive(tr_EPTF_Logging_newSelection) -> value vl_req sender v_send
  {
    v_EPTF_LoggingServer_allowReq := false;
    var integer vl_clientIdx := vl_req.Logging_NewSelection.clientIdx;
    var integer vl_selIdx := f_EPTF_LoggingServer_getNameIdxInVar(v_LoggingServer_iteratorSelectionsVarIdx, vl_req.Logging_NewSelection.name);
    if(0 > vl_selIdx){
      vl_selIdx := f_EPTF_LoggingServer_addNewNameByIdx(v_LoggingServer_iteratorSelectionsVarIdx,vl_req.Logging_NewSelection.name);
      f_EPTF_Var_newCharstringlist(
        c_LoggingServer_iteratorVarPrefix&vl_req.Logging_NewSelection.name&"."&c_LoggingServer_iteratorComponentTypes_varName,
        {},
        v_LoggingServer_iteratorComponentTypesVarIdxList[vl_selIdx]);
    }
    v_LoggingServer_selIdxMap[vl_clientIdx][vl_req.Logging_NewSelection.selectionInClient] := vl_selIdx;

    v_EPTF_LoggingServer_allowReq := true;
    EPTF_LoggingServerPort_CP.send(c_Logging_resp) to v_send;
    repeat;
  }
  [] EPTF_LoggingServerPort_CP.receive(tr_EPTF_Logging_hello) -> value vl_req sender v_send
  {
    var integer vl_clientIdx := sizeof(v_LoggingServer_clients);
    var integer vl_clientIdxInList := f_EPTF_LoggingServer_addNewNameByIdx(v_LoggingServer_iteratorClientsVarIdx, vl_req.Logging_Hello.compName);
    if(vl_clientIdx != vl_clientIdxInList){
      f_EPTF_Logging_error(true, %definitionId&": Client idx of the client "&
        vl_req.Logging_Hello.compName&" in the list is "&int2str(vl_clientIdxInList)&
        " instead of the requested "&int2str(vl_clientIdx)&". Probably there is another client with the same name.")
    }
    v_EPTF_LoggingServer_numberOfClients:=v_EPTF_LoggingServer_numberOfClients+1;
    v_LoggingServer_clients[vl_clientIdx] := v_send;
    var EPTF_Logging_Msg vl_ack; vl_ack.Logging_ClientAck.clientIdx := vl_clientIdx;
    EPTF_LoggingServerPort_CP.send(vl_ack) to v_send;
    repeat;
  }
  [] EPTF_LoggingServerPort_CP.receive(c_Logging_bye) -> value vl_req sender v_send
  {
    f_EPTF_LoggingServer_handleBy(v_send);
    repeat;
  }

}

//////////////////////////////////////////////////////////
//  Function: f_EPTF_LoggingUI_CompTypeBindToEPTFVar
// 
//  Purpose:
//    Binds the component type boolean parameters to EPTF_variables
// 
//  Parameters:
//    pl_compType - *in* *charstring* - name of the component type
//    pl_compTypeID - *in* *integer* - the ID of the component type
//    pl_selection - *in* *integer* - CORE/USER
//    pl_eventClassNames - *in* <EPTF_Logging_EventClassPrefixList> - logmasks names defined for this component type
//
//  Return Value:
//    -
// 
//  Errors:
//    - (none) 
// 
//  Detailed Comments:
//    Binds the boolean parameters to EPTF_variables.
// 
///////////////////////////////////////////////////////////

private function f_EPTF_LoggingServer_CompTypeBindToEPTFVar(
  in charstring pl_compType,
  in integer pl_compTypeID,
  in integer pl_selection,
  in EPTF_Logging_EventClassPrefixList pl_eventClassNames) runs on EPTF_LoggingServer_CT {

  //log("***********f_EPTF_LoggingUI_CompTypeBindToEPTFVar***************");

  // mask bindings
  f_EPTF_Var_newBool(
    f_EPTF_LoggingServer_typeEnabledVarName(pl_compType),
    true,
    v_EPTF_LoggingServer_componentGlobalEnableIdx[pl_compTypeID][pl_selection]);

  for(var integer i:=0; i<sizeof(pl_eventClassNames); i:=i+1) {
    f_EPTF_Var_newBool(
      f_EPTF_LoggingServer_typeClassEnabledVarName(pl_compType, pl_eventClassNames[i]),
      true,
      v_EPTF_LoggingServer_componentGlobalMaskIdx[pl_compTypeID][pl_selection][i]);
  }
}

//////////////////////////////////////////////////////////
//  Function: f_EPTF_LoggingServer_typeEnabledVarName
// 
//  Purpose:
//    Returns the name of the EPTF variable representing
//    the enabled state 
// 
public function f_EPTF_LoggingServer_typeEnabledVarName(
  in charstring pl_compType)
return charstring{
  return c_LoggingServer_componentGlobalEnablePrefix&pl_compType;
}

public function f_EPTF_LoggingServer_typeClassEnabledVarName(
  in charstring pl_compType,
  in charstring pl_className)
return charstring{
  return c_LoggingServer_componentGlobalMaskPrefix&pl_className&"."&pl_compType;
}

public function f_EPTF_LoggingServer_compNameList4TypeVarName(in charstring pl_type)
return charstring{
  return c_LoggingServer_iteratorVarPrefix&c_LoggingServer_iteratorClients_varName&"."&pl_type;
}

public function f_EPTF_LoggingServer_classNameList4TypeVarName(in charstring pl_type)
return charstring{
  return c_LoggingServer_iteratorVarPrefix&c_LoggingServer_iteratorClasses_varName&"."&pl_type;
}

private function f_EPTF_LoggingServer_getNameIdxInVar(in integer pl_varIdx, in charstring pl_name)
runs on EPTF_Var_CT
return integer{
  var EPTF_CharstringList vl_temp := f_EPTF_Var_getCharstringlistValue(pl_varIdx);
  for ( var integer i := 0; i < sizeof(vl_temp) ; i := i+1 ){
    if(vl_temp[i] == pl_name){
      return i;
    }
  }
  return -1;
}

private function f_EPTF_LoggingServer_getNameFromVar(in integer pl_varIdx, in integer pl_idx)
runs on EPTF_Var_CT
return charstring{
  if(0 <= pl_idx){
    var EPTF_CharstringList vl_temp := f_EPTF_Var_getCharstringlistValue(pl_varIdx);
    if(pl_idx < sizeof(vl_temp)){
      return vl_temp[pl_idx];
    }
  }
  return "";
}

private function f_EPTF_LoggingServer_addNewNameByIdx(in integer pl_varIdx, in charstring pl_newName)
runs on EPTF_Var_CT
return integer{
  var EPTF_CharstringList vl_temp := f_EPTF_Var_getCharstringlistValue(pl_varIdx);
  //Filter if already exsists in the list
  for ( var integer i := 0; i < sizeof(vl_temp) ; i := i+1 ){
    if(vl_temp[i] == pl_newName){
      return i;
    }
  }
  var integer vl_idx := lengthof(vl_temp);
  vl_temp[vl_idx] := pl_newName;
  f_EPTF_Var_adjustContent(pl_varIdx, {charstringlistVal := vl_temp});
  return vl_idx;
}
private function f_EPTF_LoggingServer_addNewName(in charstring pl_varName, in charstring pl_newName)
runs on EPTF_Var_CT{
  var integer vl_varId := f_EPTF_Var_getId(pl_varName);
  f_EPTF_LoggingServer_addNewNameByIdx(vl_varId, pl_newName);
}

//////////////////////////////////////////////////////////
//  Function: f_EPTF_LoggingServer_cleanup_CT
// 
//  Purpose:
//    Function to shutdown main LoggingServer component
// 
//  Parameters:
//    -
//
//  Return Value:
//    -
// 
//  Errors:
//    - (none) 
// 
//  Detailed Comments:
//    -
// 
///////////////////////////////////////////////////////////

private function f_EPTF_LoggingServer_cleanup_CT() runs on EPTF_LoggingServer_CT {
  //log("----- LoggingServer cleanup -------");
  if (v_EPTF_LoggingServer_initialized == false) {
    return;
  }  

  if (v_EPTF_LoggingServer_typesLookupTableID != -1) {
    f_EPTF_str2int_HashMap_Delete(c_LoggingServer_typesLookupTable_HashName);
    v_EPTF_LoggingServer_typesLookupTableID := -1;
  }

  var EPTF_LoggingClient_CT v_send;
  var EPTF_Logging_Msg vl_msg;
  
  v_EPTF_LoggingServer_initialized := false;
  if (v_EPTF_LoggingServer_numberOfClients==0) {
    return;
  }
  //Send bye
  for ( var integer i := 0; i < sizeof(v_LoggingServer_clients) ; i := i+1 ){
    if(null != v_LoggingServer_clients[i]){
      EPTF_LoggingServerPort_CP.send( c_Logging_bye ) to v_LoggingServer_clients[i];
    }
  }

  // wait for missing bye messages
  alt {
    [] EPTF_LoggingServerPort_CP.receive(c_Logging_bye) -> sender v_send
    {
      f_EPTF_LoggingServer_handleBy(v_send);
      if (v_EPTF_LoggingServer_numberOfClients>0) {
        repeat;
      }
      log("LoggingServer: all clients exited");
    }
    [] EPTF_LoggingServerPort_CP.receive(c_Logging_byeAck){}
    [] EPTF_LoggingServerPort_CP.receive(?) -> value vl_msg sender v_send 
    {
      f_EPTF_Common_warning(log2str("WARNING:", "Unexpected message received from ",v_send," during cleanup. Message: "&log2str(vl_msg)&" dropped"));
      repeat;
    }
  }  
}

private function f_EPTF_LoggingServer_handleBy(in EPTF_LoggingClient_CT pl_client)
runs on EPTF_LoggingServer_CT{
  //Set to null
  for ( var integer i := 0; i < sizeof(v_LoggingServer_clients) ; i := i+1 ){
    if(v_LoggingServer_clients[i]==pl_client){
      v_EPTF_LoggingServer_numberOfClients:=v_EPTF_LoggingServer_numberOfClients-1;
      f_EPTF_Logging_debug(true,log2str("v_EPTF_LoggingServer_numberOfClients:",v_EPTF_LoggingServer_numberOfClients));
      v_LoggingServer_clients[i]:=null;
      EPTF_LoggingServerPort_CP.send(c_Logging_byeAck) to pl_client;
      return;
    }
  }
  f_EPTF_Logging_warning(true, "By message arrived from an unknown client: "&log2str(pl_client));
}

private function f_EPTF_LoggingServer_getCTIdx(
  in charstring pl_cTypeName,
  in charstring pl_element)
runs on EPTF_LoggingServer_CT return integer{
  var integer vl_compTypeID;
  if(not f_EPTF_str2int_HashMap_Find(v_EPTF_LoggingServer_typesLookupTableID,pl_cTypeName,vl_compTypeID)){
    f_EPTF_Logging_warning(true, "Parameter "&c_LoggingServer_paramNameComponentType&"=="&pl_cTypeName&" is invalid for iterator or data element "&pl_element&
      ". There is no registered component type "&pl_cTypeName);
    return -1;
  }
  return vl_compTypeID;
}

private function f_EPTF_LoggingServer_DSProcessData(out charstring pl_dataVarName,
  in charstring pl_source,
  in charstring pl_ptcName,
  in charstring pl_element,
  in EPTF_DataSource_Params pl_params)
runs on EPTF_LoggingServer_CT return integer{
  select( pl_element ){
    case ( c_LoggingServer_dataElementLogEnabled ){
      const EPTF_CharstringList cl_neededParams := {
        c_LoggingServer_paramNameComponentType,
        c_LoggingServer_paramNameClass
      }
      var EPTF_CharstringList vl_params
      v_LoggingServer_dummyInt := f_EPTF_DataSourceClient_extractParams(c_LoggingServer_dataElementLogEnabled,pl_params, cl_neededParams, vl_params);
      var integer vl_mask := f_EPTF_LoggingServer_DSGetParamsMask(vl_params);
      select( vl_mask ){
        case ( 0 ){ //Global log enable
          pl_dataVarName := c_LoggingServer_allComponentGlobalEnableVarName;
          return 0;
        }
        case ( 1 ){ //Global component type log enable
          var charstring vl_ctName := vl_params[0];
          var integer vl_compTypeID := f_EPTF_LoggingServer_getCTIdx(vl_ctName,c_LoggingServer_dataElementLogEnabled);
          if(-1 == vl_compTypeID){
            return -1;
          }
          pl_dataVarName := f_EPTF_LoggingServer_typeEnabledVarName(vl_ctName);
          return 0;
        }
        case ( 3 ){ //Global LogClass of component type log enable
          var charstring vl_ctName := vl_params[0];
          var charstring vl_className := vl_params[1];
          var integer vl_compTypeID := f_EPTF_LoggingServer_getCTIdx(vl_ctName,c_LoggingServer_dataElementLogEnabled);
          if(-1 == vl_compTypeID){
            return -1;
          }
          var integer vl_clasVarId := f_EPTF_Var_getId(f_EPTF_LoggingServer_classNameList4TypeVarName(vl_ctName));
          var EPTF_CharstringList vl_classes := f_EPTF_Var_getCharstringlistValue(vl_clasVarId);
          var integer vl_classIdx := -1;
          for ( var integer i := 0; i < sizeof(vl_classes) and -1 == vl_classIdx ; i := i+1 ){
            if(vl_classes[i]==vl_className){
              vl_classIdx := i;
            }
          }
          if(-1 == vl_classIdx){
            f_EPTF_Logging_warning(true, "Parameter "&c_LoggingServer_paramNameClass&"=="&vl_className&
              " for "&c_LoggingServer_dataElementLogEnabled&" is invalid. There is no registered log class "&
              vl_className&" for component type "&vl_ctName&
              ". Available classes: "&log2str(vl_classes)&
              ". Received parameters: "&log2str(pl_params));
            return -1;
          }
          pl_dataVarName := f_EPTF_LoggingServer_typeClassEnabledVarName(vl_ctName, vl_className);
          return 0;
        }
        case ( 2 ){ //Class is set, but type not. Invalid.
          f_EPTF_Logging_warning(true, "Parameter "&c_LoggingServer_paramNameComponentType&" must be set if you set "&c_LoggingServer_paramNameClass&" for "&c_LoggingServer_dataElementLogEnabled&".");
          return -1;
        }
        case else{
          //This can not happen.
          f_EPTF_Logging_warning(true, "Invalid parameter set. Parameters can not be used in this combination. Received: "&log2str(pl_params));
          return -1;
        }
      }
    }
    case ( c_LoggingServer_iteratorClients ){
      //The clients iterator accepts no parameter, or a component type
      //No param 
      if(0 == lengthof(pl_params)){
        pl_dataVarName := c_LoggingServer_iteratorVarPrefix&c_LoggingServer_iteratorClients_varName;
        return 0;
      }else{
        //Component type
        var EPTF_CharstringList vl_params
        v_LoggingServer_dummyInt := f_EPTF_DataSourceClient_extractParams(c_LoggingServer_iteratorClients,pl_params, {c_LoggingServer_paramNameComponentType}, vl_params);
        var integer vl_compTypeID := f_EPTF_LoggingServer_getCTIdx(vl_params[0],c_LoggingServer_iteratorClients);
        if(-1 == vl_compTypeID){
          return -1;
        }
        pl_dataVarName := f_EPTF_LoggingServer_compNameList4TypeVarName(vl_params[0]);
        return 0;
      }
    }
    case ( c_LoggingServer_iteratorComponentTypes ){
      var EPTF_CharstringList vl_params
      var EPTF_CharstringList vl_list;
      f_EPTF_Logging_getSelectionList(vl_list);

      v_LoggingServer_dummyInt := f_EPTF_DataSourceClient_extractParams(c_LoggingServer_iteratorComponentTypes,pl_params, {c_LoggingServer_paramNameSelection}, vl_params);
      if("" == vl_params[0]){
        //Empty
        f_EPTF_Logging_warning(true, "Missing or empty parameter "&c_LoggingServer_paramNameSelection&" for iterator "&c_LoggingServer_iteratorComponentTypes&". It can have the following values: "&log2str(vl_list));
        return -1
      }
      pl_dataVarName := c_LoggingServer_iteratorVarPrefix&vl_params[0]&"."&c_LoggingServer_iteratorComponentTypes_varName;
      var integer vl_varId := f_EPTF_Var_getId(pl_dataVarName);
      if(0 > vl_varId){
        f_EPTF_Logging_warning(true, "Invalid selection parameter "&vl_params[0]&" for iterator "&c_LoggingServer_iteratorComponentTypes&". It can have the following values: "&log2str(vl_list));
        return -1;
      }else{
        return 0;
      }
    }
    case ( c_LoggingServer_iteratorSelectionTypes ){
      var EPTF_CharstringList vl_params
      if(-1 == f_EPTF_DataSourceClient_extractParams(c_LoggingServer_iteratorSelectionTypes, pl_params, {}, vl_params)){
        /*if(0 < sizeof(pl_params)){
        f_EPTF_Logging_warning(true, %definitionId&": Invalid parameters: "&log2str(pl_params)&
        ". Iterator "&c_LoggingServer_iteratorSelectionTypes&" has no parameters.");*/
        return -1;
      }
      pl_dataVarName := c_LoggingServer_iteratorVarPrefix&c_LoggingServer_iteratorSelectionTypes_varName;
      return 0;
    }
    case ( c_LoggingServer_iteratorClasses ){
      var EPTF_CharstringList vl_params
      v_LoggingServer_dummyInt := f_EPTF_DataSourceClient_extractParams(c_LoggingServer_iteratorClasses,pl_params, {c_LoggingServer_paramNameComponentType}, vl_params);
      //vl_params[0] is component type which registered the log classes
      if(""==vl_params[0]){
        f_EPTF_Logging_warning(true, "Missing or empty parameter "&c_LoggingServer_paramNameComponentType&" for iterator "&c_LoggingServer_iteratorClasses&".");
        return -1;
      }
      if (-1 == f_EPTF_LoggingServer_getCTIdx(vl_params[0],c_LoggingServer_iteratorClasses)){
        return -1;
      }
      pl_dataVarName := f_EPTF_LoggingServer_classNameList4TypeVarName(vl_params[0]);
      return 0;
    }
    case else{
      //Just to avoid compiler warnings
      v_LoggingServer_dummyCharstring := pl_source;
      v_LoggingServer_dummyCharstring := pl_ptcName;
      f_EPTF_Logging_warning(true, %definitionId&": Invalid iterator or external data element: "&pl_element&
        ". Available elements: "&
        c_LoggingServer_iteratorSelectionTypes&","&
        c_LoggingServer_iteratorClasses&","&
        c_LoggingServer_iteratorClients&","&
        c_LoggingServer_iteratorComponentTypes&","&
        c_LoggingServer_dataElementLogEnabled);
    }
  }
  return -1;
}

  ///////////////////////////////////////////////////////////
  //  Function: f_EPTF_LoggingServer_DSProcessDataValue
  // 
  //  Purpose:
  //    Processes the incoming DataValue requests - iterators and external data elements - and gives back the value.
  //    It should be registered in the EPTF_LoggingServer_CT. Type function fcb_EPTF_DataSourceClient_dataValueHandler
  //
  //  Parameters:
  //    *out *<EPTF_Var_DirectContent>* pl_dataValue* - the value of the data or the iterator result
  //    *in charstring pl_source* - the name of the data source 'feature'
  //    *in charstring pl_ptcName* - the name of the ptc (ID of the PTC)  
  //    *in charstring pl_element* - the name of the data element
  //    *in* <EPTF_DataSource_Params> *pl_params* - the parameters
  //      of the data for the dataElement
  //
  //  Return Value:
  //    integer - error code (0 of OK, non zero if unsuccessful: e.g. invalid parameters given in pl_params)
  //
  //  Detailed Comments: 
  //    -
  //
  ///////////////////////////////////////////////////////////
  friend function f_EPTF_LoggingServer_DSProcessDataValue(out EPTF_Var_DirectContent pl_dataValue,
                                                in charstring pl_source,
                                                in charstring pl_ptcName,
                                                in charstring pl_element,
                                                in EPTF_DataSource_Params pl_params)
  runs on EPTF_LoggingServer_CT return integer {   
    var integer vl_errorCode := -1;
    pl_dataValue := {unknownVal := {omit}}; // set it to invalid
    select( pl_element )
    {
      case(c_EPTF_DataSource_dataElement_Help) {
        vl_errorCode := f_EPTF_DataSource_handleHelp(pl_dataValue, pl_source, pl_params, c_EPTF_Logging_help);
      }
      case else
      {
      }
    }
    return vl_errorCode;
  } 


public function f_EPTF_LoggingServer_DSGetParamsMask(in EPTF_CharstringList pl_params)
//runs on EPTF_LoggingServer_CT
return integer{
  var integer vl_paramMask := 0;
  var integer vl_flag := 1;
  for ( var integer vl_i := 0; vl_i < lengthof(pl_params) ; vl_i := vl_i+1 ){
    if("" != pl_params[vl_i]){
      vl_paramMask := vl_paramMask + vl_flag;
    }
    vl_flag := vl_flag * 2;
  }

  return vl_paramMask;
}
}  // end of module
