///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2017 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_FT_Framework_Functions.ttcn
//  Description:
//  Rev:                R1A
//  Prodnr:             LPA 108 661
//  Updated:            2017-09-01
//  Contact:            http://ttcn.ericsson.se
///////////////////////////////////////////////////////////////////////////////
module IoT_FT_Framework_Functions
{
    import from IoT_FT_Framework_Definitions all;
	import from IFW_CoAP_Peer_Definitions all;
	import from IFW_CoAP_Peer_TestSteps all;
	import from IFW_HTTP_Client_Definitions all;
	import from IFW_HTTP_Client_TestSteps all;
	import from IFW_MQTT_Client_Definitions all;
	import from IFW_MQTT_Client_TestSteps all;
	import from IFW_Common all;
	
	function f_IFW_addComponent(IFW_ComponentTypes p_componentType, charstring p_addrId := "")
	runs on IFW_MAIN_CT
	return integer
	{
	  if (p_componentType == COAP_PEER) {
	    return f_IFW_addCoapPeerComponent(p_addrId);
	  }
	  else if (p_componentType == HTTP_CLIENT)
	  {
	    return f_IFW_addHttpClientComponent(p_addrId);
	  }
	  else if (p_componentType == MQTT_CLIENT)
	  {
	    return f_IFW_addMqttClientComponent(p_addrId);
	  }
	  
	  return -1;
	}
	
	function f_IFW_addCoapPeerComponent(charstring p_addrId := "") runs on IFW_MAIN_CT
	return integer
	{
		var IFW_COAP_CT v_peer := IFW_COAP_CT.create alive;
		var integer v_peerIdx := sizeof(coapPeers);
		
		coapPeers[v_peerIdx] := v_peer;
		
		var NamedHostPort v_addr;
		if (f_lookupAddress(p_addrId, v_addr))
		{
			var CoapContext v_ctx;
			f_IFW_CoapPeer_getContext(v_peerIdx, v_ctx);
			v_ctx.localHost := v_addr.hostName;
			v_ctx.localPort := v_addr.portNumber;
			
			f_IFW_CoapPeer_setContext(v_peerIdx, v_ctx);
		}
	  
		return v_peerIdx;
	}
	
	function f_IFW_addHttpClientComponent(charstring p_addrId := "") runs on IFW_MAIN_CT
	return integer
	{
		var IFW_HTTP_Client_CT v_client := IFW_HTTP_Client_CT.create alive;
		var integer v_clientIdx := sizeof(httpClients);
		
		httpClients[v_clientIdx] := v_client;
		
		var NamedHostPort v_addr;
		if (f_lookupAddress(p_addrId, v_addr))
		{
			var HttpClientContext v_ctx;
			f_IFW_HttpClient_getContext(v_clientIdx, v_ctx);
			v_ctx.localHost := v_addr.hostName;
			v_ctx.localPort := v_addr.portNumber;
			
			f_IFW_HttpClient_setContext(v_clientIdx, v_ctx);
		}
	  
		return v_clientIdx;
	}
	
	function f_IFW_addMqttClientComponent(charstring p_addrId := "") runs on IFW_MAIN_CT
	return integer
	{
		var IFW_MQTT_Client_CT v_client := IFW_MQTT_Client_CT.create alive;
		var integer v_clientIdx := sizeof(mqttClients);
		
		mqttClients[v_clientIdx] := v_client;
		
		var NamedHostPort v_addr;
		if (f_lookupAddress(p_addrId, v_addr))
		{
			var MqttClientContext v_ctx;
			f_IFW_MqttClient_getContext(v_clientIdx, v_ctx);
			v_ctx.localHost := v_addr.hostName;
			v_ctx.localPort := v_addr.portNumber;
			
			f_IFW_MqttClient_setContext(v_clientIdx, v_ctx);
		}
	  
		return v_clientIdx;
	}
	
	function f_IFW_initComponents() runs on IFW_MAIN_CT
	{
	  setverdict(pass);
	  mid := float2int(int2float(65000)*rnd());
	  
	  for (var integer i:=0; i<sizeof(coapPeers); i:=i+1) {
	    f_IFW_CoapPeer_init(i);
	  }
	  for (var integer i:=0; i<sizeof(httpClients); i:=i+1) {
	    f_IFW_HttpClient_init(i);
	  }
	  for (var integer i:=0; i<sizeof(mqttClients); i:=i+1) {
	    f_IFW_MqttClient_init(i);
	  }
	}
	
	function f_IFW_cleanUp() runs on IFW_MAIN_CT
	{
	  for (var integer i:=0; i<sizeof(httpClients); i:=i+1) {
	    f_IFW_HttpClient_cleanUp(i);
	  }
	  for (var integer i:=0; i<sizeof(mqttClients); i:=i+1) {
	    f_IFW_MqttClient_cleanUp(i);
	  }
	  stop;
	}
}
