///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2020 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_Server_TestSteps.ttcn
//  Description:
//  Rev:                <RnXnn>
//  Prodnr:             CNL 113 910
//  Updated:            2020-03-06
//  Contact:            http://ttcn.ericsson.se
///////////////////////////////////////////////////////////////////////////////
module IFW_HTTP_Server_TestSteps 
{

 import from IoT_FT_Framework_Definitions all;
 import from IFW_Common all;
 import from IFW_HTTP_Server_Definitions all;
 import from IFW_HTTP_Server_Functions all;
 import from HTTPmsg_Types all;
	
  function f_IFW_HttpServer_init(in integer p_serverIdx) runs on IFW_MAIN_CT
  return boolean
  {
    var IFW_HTTP_Server_CT v_server := httpServers[p_serverIdx];	  
    if (v_server == null) { log("IFW: No http server found"); return false; }
    f_isRunningGuard(v_server);

    v_server.start(f_HTTP_Server_init());
    v_server.done;

    return true;	  
  }
	
  function f_IFW_HttpServer_cleanUp(in integer p_serverIdx) runs on IFW_MAIN_CT
  return boolean
  {
    var IFW_HTTP_Server_CT v_server := httpServers[p_serverIdx];
    if (v_server == null) { log("IFW: No http server found"); return false; }
    f_isRunningGuard(v_server);

    v_server.start(f_HTTP_Server_cleanUp());
    v_server.done;

    return true;	  
  }
	
  function f_IFW_HttpServer_getContext(in integer p_serverIdx, out HttpServerContext p_httpServerContext) runs on IFW_MAIN_CT
  return boolean
  {
    var IFW_HTTP_Server_CT v_server := httpServers[p_serverIdx];
    if (v_server == null) { log("IFW: No http server found"); return false; }	  
    f_isRunningGuard(v_server);

    v_server.start(f_HTTP_Server_getContext());
    v_server.done(HttpServerContext:?) -> value p_httpServerContext;

    return true;
  }
	
  function f_IFW_HttpServer_setContext(in integer p_serverIdx, in HttpServerContext p_httpServerContext) runs on IFW_MAIN_CT
  return boolean
  {
    var IFW_HTTP_Server_CT v_server := httpServers[p_serverIdx];	  
    if (v_server == null) { log("IFW: No http server found"); return false; }	  
    f_isRunningGuard(v_server);

    v_server.start(f_HTTP_Server_setContext(p_httpServerContext));
    v_server.done;

    return true;
  }	
	
  function f_IFW_HttpServer_setMessageToSend(in integer p_serverIdx, HTTPMessage p_msg) runs on IFW_MAIN_CT
  return boolean
  {
    var IFW_HTTP_Server_CT v_server := httpServers[p_serverIdx];	  
    if (v_server == null) { log("IFW: No http server found"); return false; }	  
    f_isRunningGuard(v_server);

    v_server.start(f_HTTP_Server_setMessageToSend(p_msg));
    v_server.done;

    return true;
  }
	
  function f_IFW_HttpServer_send(in integer p_serverIdx) runs on IFW_MAIN_CT
  return boolean
  {
    var IFW_HTTP_Server_CT v_server := httpServers[p_serverIdx];	  
    if (v_server == null) { log("IFW: No http server found"); return false; }	  
    f_isRunningGuard(v_server);

    v_server.start(f_HTTP_Server_send());
    v_server.done;

    return true;
  }

  function f_IFW_HttpServer_receive(in integer p_serverIdx) runs on IFW_MAIN_CT
  return boolean
  {
    var IFW_HTTP_Server_CT v_server := httpServers[p_serverIdx];	  
    if (v_server == null) { log("IFW: No http server found"); return false; }	  
    f_isRunningGuard(v_server);

    v_server.start(f_HTTP_Server_receive());
    v_server.done;

    return true;
  }

  function f_IFW_HttpServer_check(in integer p_serverIdx, template HTTPMessage p_msg) runs on IFW_MAIN_CT
  return boolean
  {
    var boolean v_ret;
    var IFW_HTTP_Server_CT v_server := httpServers[p_serverIdx];	  
    if (v_server == null) { log("IFW: No http server found"); return false; }	  
    f_isRunningGuard(v_server);

    v_server.start(f_HTTP_Server_check(p_msg));
    v_server.done(ReturnBoolean:?) -> value v_ret; 

    return v_ret;
  }
	
  function f_IFW_HttpServer_close(in integer p_serverIdx) runs on IFW_MAIN_CT
  return boolean
  {
    var IFW_HTTP_Server_CT v_server := httpServers[p_serverIdx];
    if (v_server == null) { log("IFW: No http server found"); return false; }
    f_isRunningGuard(v_server);

    v_server.start(f_HTTP_Server_close());
    v_server.done;

    return true;	  
  }
}
