///////////////////////////////////////////////////////////////////////////////
//
// 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 v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
///////////////////////////////////////////////////////////////////////////////
//  File:               IFW_HTTP_Client_Functions.ttcn
//  Description:
//  Rev:                R1A
//  Prodnr:             LPA 108 661
//  Updated:            2017-09-01
//  Contact:            http://ttcn.ericsson.se
///////////////////////////////////////////////////////////////////////////////
module IFW_HTTP_Client_TestSteps {

    import from IoT_FT_Framework_Definitions all;
    import from IFW_Common all;
    import from IFW_HTTP_Client_Definitions all;
    import from IFW_HTTP_Client_Functions all;
	import from HTTPmsg_Types all;
	
	
	function f_IFW_HttpClient_init(in integer p_clientIdx) runs on IFW_MAIN_CT
	return boolean
	{
	  var IFW_HTTP_Client_CT v_client := httpClients[p_clientIdx];	  
	  if (v_client == null) { log("IFW: No http client found"); return false; }	  
	  f_isRunningGuard(v_client);
	  
	  v_client.start(f_HTTP_Client_init());
      v_client.done;
      
	  return true;	  
	}
	
	function f_IFW_HttpClient_cleanUp(in integer p_clientIdx) runs on IFW_MAIN_CT
	return boolean
	{
	  var IFW_HTTP_Client_CT v_client := httpClients[p_clientIdx];	  
	  if (v_client == null) { log("IFW: No http client found"); return false; }	  
	  f_isRunningGuard(v_client);
	  
	  v_client.start(f_HTTP_Client_cleanUp());
      v_client.done;
      
	  return true;	  
	}
	
	function f_IFW_HttpClient_setRemote(in integer p_clientIdx, in charstring p_remoteAddrId) runs on IFW_MAIN_CT
	return boolean
	{
 		var NamedHostPort v_addr;
		if (f_lookupAddress(p_remoteAddrId, v_addr))
		{
			var HttpClientContext v_ctx;
			f_IFW_HttpClient_getContext(p_clientIdx, v_ctx);
			v_ctx.remoteHost := v_addr.hostName;
			v_ctx.remotePort := v_addr.portNumber;
			
			f_IFW_HttpClient_setContext(p_clientIdx, v_ctx);
		}
		return true;
	}	
	
	function f_IFW_HttpClient_getContext(in integer p_clientIdx, out HttpClientContext p_httpClientContext) runs on IFW_MAIN_CT
	return boolean
	{
	  var IFW_HTTP_Client_CT v_client := httpClients[p_clientIdx];
	  if (v_client == null) { log("IFW: No http client found"); return false; }	  
	  f_isRunningGuard(v_client);
	  
	  v_client.start(f_HTTP_Client_getContext());
      v_client.done(HttpClientContext:?) -> value p_httpClientContext;
      
	  return true;
	}
	
	function f_IFW_HttpClient_setContext(in integer p_clientIdx, in HttpClientContext p_httpClientContext) runs on IFW_MAIN_CT
	return boolean
	{
	  var IFW_HTTP_Client_CT v_client := httpClients[p_clientIdx];	  
	  if (v_client == null) { log("IFW: No http client found"); return false; }	  
	  f_isRunningGuard(v_client);
	  
	  v_client.start(f_HTTP_Client_setContext(p_httpClientContext));
      v_client.done;
      
	  return true;
	}	
	
    function f_IFW_HttpClient_setMessageToSend(in integer p_clientIdx, HTTPMessage p_msg) runs on IFW_MAIN_CT
	return boolean
	{
	  var IFW_HTTP_Client_CT v_client := httpClients[p_clientIdx];	  
	  if (v_client == null) { log("IFW: No http client found"); return false; }	  
	  f_isRunningGuard(v_client);
	  
	  v_client.start(f_HTTP_Client_setMessageToSend(p_msg));
      v_client.done;
      
	  return true;
	}
	
	function f_IFW_HttpClient_send(in integer p_clientIdx) runs on IFW_MAIN_CT
	return boolean
	{
	  var IFW_HTTP_Client_CT v_client := httpClients[p_clientIdx];	  
	  if (v_client == null) { log("IFW: No http client found"); return false; }	  
	  f_isRunningGuard(v_client);
	  
	  v_client.start(f_HTTP_Client_send());
      v_client.done;
      
	  return true;
	}
	
	function f_IFW_HttpClient_receive(in integer p_clientIdx) runs on IFW_MAIN_CT
	return boolean
	{
	  var IFW_HTTP_Client_CT v_client := httpClients[p_clientIdx];	  
	  if (v_client == null) { log("IFW: No http client found"); return false; }	  
	  f_isRunningGuard(v_client);
	  
	  v_client.start(f_HTTP_Client_receive());
      v_client.done;
      
	  return true;
	}
	
	function f_IFW_HttpClient_check(in integer p_clientIdx, template HTTPMessage p_msg) runs on IFW_MAIN_CT
	return boolean
	{
	  var boolean v_ret;
	  var IFW_HTTP_Client_CT v_client := httpClients[p_clientIdx];	  
	  if (v_client == null) { log("IFW: No http client found"); return false; }	  
	  f_isRunningGuard(v_client);
	  
	  v_client.start(f_HTTP_Client_check(p_msg));
      v_client.done(ReturnBoolean:?) -> value v_ret; 
      
	  return v_ret;
	}	
    
  function f_HTTP_setCommonRequestHeaders(in integer p_clientIdx) runs on IFW_MAIN_CT
  {
    var HttpClientContext v_httpClientCtx;
	f_IFW_HttpClient_getContext(p_clientIdx, v_httpClientCtx);
	v_httpClientCtx.requestHeaders :=
	{
      {"Host", v_httpClientCtx.remoteHost & ":" & int2str(v_httpClientCtx.remotePort)},
      {"User-Agent", "IoT_FT_Framework"}
	}	
	f_IFW_HttpClient_setContext(p_clientIdx, v_httpClientCtx);
  }
}
