///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2021 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:               IFW_HTTP_Client_Functions.ttcn
//  Description:
//  Rev:                R1B
//  Prodnr:             CNL 113 910
//  Updated:            2021-02-03
//  Contact:            http://ttcn.ericsson.se
///////////////////////////////////////////////////////////////////////////////
module IFW_HTTP_Client_Functions
{
    import from IFW_HTTP_Client_Definitions all;
	import from HTTPmsg_Types all;
	import from IPL4asp_Types all;
	import from IPL4asp_PortType all;
	import from IFW_Common all;
	import from TCCMessageHandling_Functions all;
import from HTTPmsg_MessageLen all;

	
  ///////////////////////////////////////////////////////////
  //  Module parameter: tsp_HTTP_Client_maxResponseTime
  // 
  //  Purpose:
  //    Time the client is waiting for a response message (0.0->not set)
  //
  //  Type:
  //     *float*
  //
  //  Default value:
  //     *0.0*
  ///////////////////////////////////////////////////////////
	modulepar float tsp_HTTP_Client_maxResponseTime := 0.0;

	function f_HTTP_Client_init() runs on IFW_HTTP_Client_CT
    {
		log(%definitionId, " started");
		var Result vl_result;
    
		log("Mapping started");
		map(self:IPL4_PCO,system:IPL4_PCO);
		var f_IPL4_getMsgLen vl_f := refers(f_HTTP_Client_getMessageLength);
		f_IPL4_setGetMsgLen(IPL4_PCO, -1, vl_f, {});
    
		log("Connecting the socket to the remote");
		vl_result := f_IPL4_connect(IPL4_PCO, ctx.remoteHost, ctx.remotePort, ctx.localHost, ctx.localPort, -1, {tcp := {}}, {{reuseAddress := {enable := true}}});
		f_checkResult(vl_result);
		ctx.connId := vl_result.connId;
		
		log(%definitionId, " finished");
	}
	
	function f_HTTP_Client_connect() runs on IFW_HTTP_Client_CT
	{
		log(%definitionId, " started");
		var Result vl_result;
    
		log("Connecting the socket to the remote");
                vl_result := f_IPL4_connect(IPL4_PCO, ctx.remoteHost, ctx.remotePort, ctx.localHost, ctx.localPort, -1, {tcp := {}}, {{reuseAddress := {enable := true}}});
		f_checkResult(vl_result);
		ctx.connId := vl_result.connId;
	        log("ctx.connId: ", ctx.connId);
		
		log(%definitionId, " finished");
	}
	
	function f_HTTP_Client_cleanUp() runs on IFW_HTTP_Client_CT
    {
		log(%definitionId, " started");
		var Result vl_result;
    
		log("Closing connection");
		if (ctx.connId >= 0)
		{
		  vl_result := f_IPL4_close(IPL4_PCO, ctx.connId, {tcp := {}});
		  //f_checkResult(vl_result);		  
		}
	
		log(%definitionId, " finished");
	}
	
	function f_HTTP_Client_getContext() runs on IFW_HTTP_Client_CT
	return HttpClientContext
	{
		return ctx;
	}
	
	function f_HTTP_Client_setContext(in HttpClientContext p_ctx) runs on IFW_HTTP_Client_CT
	{
	  ctx := p_ctx;
	}
	
	function f_HTTP_Client_setMessageToSend(in HTTPMessage p_msg) runs on IFW_HTTP_Client_CT
	{
	  msgToSend := p_msg;
	  
	  if (ischosen(msgToSend.request))
	  {
  	    for (var integer i:=0; i<sizeof(ctx.requestHeaders); i:=i+1)
	    {
	      if (f_HTTP_lookupHeader(ctx.requestHeaders[i].header_name, msgToSend.request.header) == -1)
	      {
	        msgToSend.request.header[sizeof(msgToSend.request.header)] := ctx.requestHeaders[i];
	      }
	      else
	      {
	        log("HTTP Client: Didn't add request header because a header with the same name is already there ", ctx.requestHeaders[i]);
	      }
	    }
      }
	}	
	
    function f_HTTP_Client_send() runs on IFW_HTTP_Client_CT
	{
	  	var octetstring v_encoded;
	  	
	  	v_encoded := enc_HTTPMessage(msgToSend);
	  
	  	var ASP_SendTo vl_send;

		vl_send.connId := ctx.connId;
		vl_send.remName := ctx.remoteHost;
		vl_send.remPort := ctx.remotePort;
		vl_send.proto := {tcp := {}}

		vl_send.msg := v_encoded;

		log("HTTP PDU: ", msgToSend);
		IPL4_PCO.send(vl_send);
	}
	
	function f_HTTP_Client_receive() runs on IFW_HTTP_Client_CT
	{
	  // Activate default
	  
	  timer t_Timeout := tsp_HTTP_Client_maxResponseTime;
	  if (tsp_HTTP_Client_maxResponseTime > 0.0) { t_Timeout.start; }
	  
	  var ASP_RecvFrom v_ipl4Recv;
	  var ASP_Event v_ipl4Event;
	  
	  alt
	  {
	    [] IPL4_PCO.receive(ASP_RecvFrom:?) -> value v_ipl4Recv
	    {
	      log("Received: ", v_ipl4Recv);
	      
	      var HTTPMessage v_httpMsg;
	      dec_HTTPMessage(v_ipl4Recv.msg, v_httpMsg);
	      
          lastReceived := v_httpMsg;
          log("HTTP PDU: ", lastReceived);          
	    }
	    [] IPL4_PCO.receive(ASP_Event:?) -> value v_ipl4Event
	    {
	      log("Received: ", v_ipl4Event);
	      repeat;
	    }
	    [] t_Timeout.timeout
	    {
	      lastReceived := c_HTTPMessage_empty;
	    }
	    
	    // Deactivate default
	  }
	}
	
	function f_HTTP_Client_check(in template HTTPMessage p_expected) runs on IFW_HTTP_Client_CT
	return ReturnBoolean
	{
	  if (not match(lastReceived, p_expected)) 
	  {
		  log("CHECK: last received is not matching with expected template");
		  return false;
	  }
		
		log("CHECK: return true");
		return true;
	}
	
	function f_HTTP_Client_getMessageLength(in octetstring stream, inout ro_integer args)
    return integer
    {
//      return f_TCCMessageHandling_getMessageLength(stream)
return f_HTTPMessage_len(stream);

    }
    
    function f_HTTP_lookupHeader(charstring p_headerName, in HeaderLines p_headers)
    return integer
    {
      for (var integer i:=0; i<sizeof(p_headers); i:=i+1)
      {
        if (p_headers[i].header_name == p_headerName) { return i; }
      }
      return -1;
    }
}
