///////////////////////////////////////////////////////////////////////////////
//                                                                           //
// Copyright (c) 2000-2019 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                                 //
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////
//  Module: Rendezvous_Demo
// 
//  Purpose:
//    Creates and manages a RendezvousServer to provide synchronization among various entities.
// 
///////////////////////////////////////////////////////////

module EPTF_Rendezvous_Demo
{


import from EPTF_CLL_RendezvousClient_Functions all;
import from EPTF_CLL_Rendezvous_Functions all;
import from EPTF_CLL_Rendezvous_Definitions all;

import from EPTF_CLL_Base_Functions all;
import from EPTF_CLL_Base_Definitions all;

type component SYSTEM_CT{
}

type component MAIN_CT extends EPTF_Base_CT{
}

type component Client_CT extends EPTF_RendezvousClient_CT{
}

function f_RendezvousClient_Behaviour1(in charstring pl_selfName, in
  EPTF_Rendezvous_CT pl_server) runs on Client_CT{
  log("----- Client Behaviour START -------");
  f_EPTF_RendezvousClient_init_CT(pl_selfName,pl_server);


  var integer vl_Idx;
  vl_Idx:=f_EPTF_RendezvousClient_StartWaitForATrigger(100);
  
  if(f_EPTF_RendezvousClient_WaitForResponse(vl_Idx))
  {
    log("---Trigger received---");
  }
  
  setverdict(pass); 
  log("----- Client Behaviour stop -------");
  f_EPTF_Base_cleanup_CT(); 
}


function f_RendezvousClient_Behaviour2(in charstring pl_selfName, in
  EPTF_Rendezvous_CT pl_server) runs on Client_CT{
  log("----- Client Behaviour START -------");
  f_EPTF_RendezvousClient_init_CT(pl_selfName,pl_server);

  var integer vl_Idx;
  timer t_wait := 2.0;
  t_wait.start;
  t_wait.timeout
  {
    vl_Idx:=f_EPTF_RendezvousClient_StartWaitForATrigger(100);
  }

  if(f_EPTF_RendezvousClient_WaitForResponse(vl_Idx))
  {
    log("---Trigger received---");
  }

  setverdict(pass); 
  log("----- Client Behaviour stop -------");
  f_EPTF_Base_cleanup_CT(); 
}

function f_RendezvousClient_WaitForNTrigger_Behaviour(in charstring pl_selfName, in
  EPTF_Rendezvous_CT pl_server) runs on Client_CT{
  log("----- Client WaitForNTrigger Behaviour START -------");
  f_EPTF_RendezvousClient_init_CT(pl_selfName,pl_server);

  var integer vl_Idx;
  vl_Idx:=f_EPTF_RendezvousClient_StartWaitForNTrigger(11,3);
  
  if(f_EPTF_RendezvousClient_WaitForResponse(vl_Idx))
  {
    log("---Trigger received---");
  }

  setverdict(pass); 
  log("----- Client Behaviour stop -------");
  f_EPTF_Base_cleanup_CT(); 
}

function f_logBusy(in charstring rendezvousID, in integer rendezvousID_int) runs on Client_CT{
  log(f_EPTF_Base_selfName(), " got a NOTIFY!: ", rendezvousID, rendezvousID_int);
  setverdict(pass);
}

function f_RendezvousClient_StateTrigger_Behaviour(in charstring pl_selfName, in
  EPTF_Rendezvous_CT pl_server, in boolean perm:= false) runs on Client_CT{
  log("----- Client StateNTrigger Behaviour START -------");
  f_EPTF_RendezvousClient_init_CT(pl_selfName,pl_server);

  f_EPTF_RendezvousClient_SubscribeToState("User23456_BUSY", refers(f_logBusy), perm);

  timer t_waitProv := 4.0;
  t_waitProv.start;
  t_waitProv.timeout;
  if (perm){
    f_EPTF_RendezvousClient_Unsubscribe("User23456_BUSY");
  } else {
    f_EPTF_RendezvousClient_SubscribeToState("User23456_BUSY", refers(f_logBusy), perm);
  }
  t_waitProv.start;
  t_waitProv.timeout;

  log("----- Client Behaviour stop -------");
  f_EPTF_Base_cleanup_CT();
}

function f_RendezvousClient_StateTrigger_Behaviour1(in charstring pl_selfName, in
  EPTF_Rendezvous_CT pl_server) runs on Client_CT{
  log("----- Client StateTrigger Behaviour START -------");
  f_EPTF_RendezvousClient_init_CT(pl_selfName,pl_server);

  timer t_waitProv := 2.0;
  t_waitProv.start;
  t_waitProv.timeout;

  f_EPTF_RendezvousClient_NewState("User23456_BUSY",2345);

  t_waitProv.start;
  t_waitProv.timeout;

  f_EPTF_RendezvousClient_NewState("User23456_BUSY");

  t_waitProv.start;
  t_waitProv.timeout;

  setverdict(pass);
  log("----- Client Behaviour stop -------");
  f_EPTF_Base_cleanup_CT(); 
}



function f_RendezvousServer_behaviour(charstring pl_selfName) runs on EPTF_Rendezvous_CT {
  log("----- RendezvousServer START -------");
  f_EPTF_Rendezvous_init_CT(pl_selfName);

  timer t_waitProv := 15.0;

  t_waitProv.start;
  alt {
    [] t_waitProv.timeout{
      t_waitProv.start;repeat;
    }
  }
  setverdict(pass); 
  f_EPTF_Base_cleanup_CT();
  log("----- RendezvousServer shutdown -------");  
}



testcase tc_WaitForATriggerDemo() runs on MAIN_CT system SYSTEM_CT{

  //Server
  var EPTF_Rendezvous_CT ct_server := EPTF_Rendezvous_CT.create;

  //Starting Server
  ct_server.start(f_RendezvousServer_behaviour("RendezvousServer"));

  //Client1
  var Client_CT ct_client1 := Client_CT.create;

  //Starting Client
  ct_client1.start(f_RendezvousClient_Behaviour1("RendezvousClient1", ct_server));

  //Client2
  var Client_CT ct_client2 := Client_CT.create;

  //Starting Client
  ct_client2.start(f_RendezvousClient_Behaviour2("RendezvousClient2", ct_server));


  timer T_main := 10.0;
  T_main.start;
  alt {
    [] ct_server.done {}
    [] T_main.timeout{}
  }
  //all component.done;

  f_EPTF_Base_cleanup_CT();

}

testcase tc_StateTriggerDemo() runs on MAIN_CT system SYSTEM_CT{

  //Server
  var EPTF_Rendezvous_CT ct_server := EPTF_Rendezvous_CT.create;

  //Starting Server
  ct_server.start(f_RendezvousServer_behaviour("RendezvousServer"));

  //Client1
  var Client_CT ct_client1 := Client_CT.create;

  //Starting Client
  ct_client1.start(f_RendezvousClient_StateTrigger_Behaviour("RendezvousClient1", ct_server, true));

  //Client2
  var Client_CT ct_client2 := Client_CT.create;

  //Starting Client
  ct_client2.start(f_RendezvousClient_StateTrigger_Behaviour1("RendezvousClient2", ct_server));

  //Client3
  var Client_CT ct_client3 := Client_CT.create;

  //Starting Client
  ct_client3.start(f_RendezvousClient_StateTrigger_Behaviour("RendezvousClient3", ct_server));

  timer T_main := 15.0;
  T_main.start;
  alt {
    [] ct_server.done {}
    [] T_main.timeout{}
  }
  //all component.done;
  
  f_EPTF_Base_cleanup_CT();
  
}

testcase tc_WaitForNTriggerDemo() runs on MAIN_CT system SYSTEM_CT{

  //Server
  var EPTF_Rendezvous_CT ct_server := EPTF_Rendezvous_CT.create;

  //Starting Server
  ct_server.start(f_RendezvousServer_behaviour("RendezvousServer"));

  //Client1
  var Client_CT ct_client1 := Client_CT.create;

  //Starting Client
  ct_client1.start(f_RendezvousClient_WaitForNTrigger_Behaviour("RendezvousClient1", ct_server));

  //Client2
  var Client_CT ct_client2 := Client_CT.create;

  //Starting Client
  ct_client2.start(f_RendezvousClient_WaitForNTrigger_Behaviour("RendezvousClient2", ct_server));

  //Client3
  var Client_CT ct_client3 := Client_CT.create;

  //Starting Client
  ct_client3.start(f_RendezvousClient_WaitForNTrigger_Behaviour("RendezvousClient3", ct_server));

  timer T_main := 15.0;
  T_main.start;
  alt {
    [] ct_server.done {}
    [] T_main.timeout{}
  }
  //all component.done;
  
  f_EPTF_Base_cleanup_CT();
  
}

control
{
  execute(tc_WaitForATriggerDemo());
  execute(tc_WaitForNTriggerDemo());
  execute(tc_StateTriggerDemo());
}

}  // end of module
