/******************************************************************************
 * Copyright (c) ETSI 2017.
 *
 * This file is subject to copyrights owned by ETSI. Non-exclusive permission
 * is hereby granted, free of charge, to copy, reproduce and amend this file
 * under the following conditions: It is provided "as is", without warranty of any
 * kind, expressed or implied.
 * 
 * ETSI shall never be liable for any claim, damages, or other liability arising
 * from its use or inability of use.This permission does not apply to any documentation
 * associated with this file for which ETSI keeps all rights reserved. The present
 * copyright notice shall be included in all copies of whole or part of this
 * file and shall not imply any sub-license right.
 *
 * Modified by: Adrien Kirjak
 *
 ** @version  0.0.1
 ** @purpose  1:13, Port with type anytype can send and receive messages of any basic or structured type: 'universal charstring' type.
 ** @verdict  pass accept, ttcn3verdict:pass
 ***************************************************/

// #reqname  /Requirements/13 Declaring messages/Any type can be declared as type of message in a message port type
 

module Sem_13_toplevel_declaring_msg_various_types_013{
    type record CompositeType{
        integer i
    }

    type set MySet{
        integer int1,
        charstring str1
    }

    type enumerated MyEnum{
        Perl,Bash,Python
    }

    type integer MyArray[3];

    type union MyUnion{
        integer int,
        float real
    }

    type record MsgType1{
        integer i,
        float k,
        boolean b,
        verdicttype v,
        bitstring bs,
        hexstring hs,
        octetstring os,
        charstring cs,
        universal charstring ucs,
        CompositeType rec1,
        MySet set1,
        MyUnion union1,
        MyEnum enum1,
        MyArray arr1
    }

    type record MsgType2{
            integer j
    }

    type port MyPort message{
        inout integer;
        inout float;
        inout boolean;
        inout verdicttype;
        inout bitstring;
        inout hexstring;
        inout octetstring;
        inout charstring; // conflict 
        inout universal charstring;
        inout CompositeType;
        inout MySet;
        inout MyUnion;
        inout MyEnum;
        inout MyArray;
    } with {extension "internal"}

    type component Sender{
        timer t_timer := 2.0;
        port MyPort src;
    }
    
    type component Receiver{
        port MyPort dst;
    }

    type component MTC {}
	   
    function make_union() return MyUnion
    {
        var MyUnion result;
        result.int := 1;
        return result;
    }
	
    const MsgType1 c_values := {
        i := 1, 
        k := 1.0, 
        b := true, 
        v := pass, 
        bs := '0101'B, 
        hs := '123ABD'H, 
        os := 'FF96'O,
        cs := "ab", 
        ucs := "the", 
        rec1 := {1},
        set1 := {int1:=1, str1:="the"}, 
        union1 := { int := 1}, 
        enum1 := Bash, 
        arr1 := {1,2,3}
    };

    function f_sender() runs on Sender 
    {
        // universal charstring        
        t_timer.start;
        src.send(c_values.ucs);
        alt {
            [] src.receive(c_values.ucs) { setverdict(pass); }
			[] src.receive { 
				setverdict(fail, "Unexpected data, expected universal charstring ", c_values.ucs); 
				stop; 
			}
			[] t_timer.timeout {
				setverdict(fail, "No response from echo service");
				stop;
			}
        }
    } 
	
	function f_receiver() runs on Receiver 
	{
		var charstring cc;
		
	    timer t_timer := 30.0;
	    t_timer.start;
	    alt 
	    {
            [] dst.receive(universal charstring:"the") { setverdict(pass); dst.send(c_values.ucs); }
	        
            [] dst.receive  { 
				setverdict(fail, "Unexpected messagem expected universal charstring", c_values.ucs); stop; }
	        [] t_timer.timeout { setverdict(fail, "No more messages"); stop; }
	    }
	} 
	
    testcase TC_Sem_13_toplevel_declaring_msg_various_types_013() runs on MTC system MTC
    {
		var Sender c_sender := Sender.create;
		var Receiver c_receiver := Receiver.create;
        connect(c_sender:src, c_receiver:dst);
        c_sender.start(f_sender());
        c_receiver.start(f_receiver());
        c_sender.done;
        c_receiver.kill;
    }
    control {
            execute(TC_Sem_13_toplevel_declaring_msg_various_types_013())
    }
}
