///////////////////////////////////////////////////////////////////////////////
//
// 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_MQTT_Server_Functions.ttcn
//  Description:
//  Rev:                <RnXnn>
//  Prodnr:             CNL 113 910
//  Updated:            2020-03-06
//  Contact:            http://ttcn.ericsson.se
///////////////////////////////////////////////////////////////////////////////
module IFW_MQTT_Server_Functions
{
  import from IFW_MQTT_Server_Definitions all;
  import from MQTT_v3_1_1_Types all;
  import from MQTT_v3_1_1_IPL4SizeFunction all;
  import from IPL4asp_Types all;
  import from IPL4asp_PortType all;
  import from IFW_Common all;
  import from TCCMessageHandling_Functions all;

  function f_MQTT_Server_init() runs on IFW_MQTT_Server_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_GetMsgLengthMQTT);
    f_IPL4_setGetMsgLen(IPL4_PCO, -1, vl_f, {});

    log("Creating the server socket");
    vl_result := f_IPL4_listen(IPL4_PCO, ctx.localHost, ctx.localPort, {tcp := {}}, {{reuseAddress := {enable := true}}});
    f_checkResult(vl_result);
    ctx.serverConnId := vl_result.connId;

    log(%definitionId, " finished");
  }	

  function f_MQTT_Server_cleanUp() runs on IFW_MQTT_Server_CT
  {
    log(%definitionId, " started");
    var Result vl_result;

    log("Closing connection");
    if (ctx.serverConnId >= 0)
    {
      vl_result := f_IPL4_close(IPL4_PCO, ctx.serverConnId, {tcp := {}});
      //f_checkResult(vl_result);		  
    }

    log(%definitionId, " finished");
  }
	
  function f_MQTT_Server_getContext() runs on IFW_MQTT_Server_CT
  return MqttServerContext
  {
    return ctx;
  }
	
  function f_MQTT_Server_setContext(in MqttServerContext p_ctx) runs on IFW_MQTT_Server_CT
  {
    ctx := p_ctx;
  }
	
  function f_MQTT_Server_setMessageToSend(in MQTT_v3_1_1_ReqResp p_msg) runs on IFW_MQTT_Server_CT
  {
    msgToSend := p_msg;
  }	
	
  function f_MQTT_Server_send() runs on IFW_MQTT_Server_CT
  {
    var octetstring v_encoded := ''O;

    f_MQTT_v3_1_1_enc({ msg := msgToSend}, v_encoded);

    var ASP_SendTo vl_send;

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

    vl_send.msg := v_encoded;

    log("MQTT PDU: ", msgToSend);
    log("IPL4 PDU: ", vl_send);
    IPL4_PCO.send(vl_send);
  }
	
  function f_MQTT_Server_receive(in float p_maxWait := 10.0) runs on IFW_MQTT_Server_CT
  {
    timer t_Timeout := p_maxWait;
    if (p_maxWait > 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);

        if (ispresent(v_ipl4Recv.connId)) { ctx.clientConnId := v_ipl4Recv.connId; }

        var MQTT_v3_1_1_Message v_mqttMsg;
	f_MQTT_v3_1_1_dec(v_ipl4Recv.msg, v_mqttMsg);

        if (ischosen(v_mqttMsg.msg))
        {
          lastReceived := v_mqttMsg.msg;
          log("MQTT PDU: ", lastReceived);          
        }
        else {
          lastReceived := c_MQTTMessage_empty;
          log("MQTT PDU [raw]:",v_mqttMsg);
        }
          
        ctx.remoteHost := v_ipl4Recv.remName;
        ctx.remotePort := v_ipl4Recv.remPort;
        log("IPL4 PDU: ", lastReceived);
      }
      [] IPL4_PCO.receive(ASP_Event:?) -> value v_ipl4Event
      {
	log("Received: ", v_ipl4Event);
	repeat;
      }
      [] t_Timeout.timeout
      {
	lastReceived := c_MQTTMessage_empty;
      }
    }
  }
  
  function f_MQTT_Server_check(in template MQTT_v3_1_1_ReqResp p_expected) runs on IFW_MQTT_Server_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_MQTT_Server_close() runs on IFW_MQTT_Server_CT
  {
    log(%definitionId, " started");
    var Result vl_result;

    log("Closing connection");
    if (ctx.serverConnId >= 0)
    {
      vl_result := f_IPL4_close(IPL4_PCO, ctx.serverConnId, {tcp := {}});
      //f_checkResult(vl_result);		  
    }

    log(%definitionId, " finished");
  }

}
