/*
* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org>
* License: BSD
* This file is part of Open Source sipML5 solution <http://www.sipml5.org>
*/
%%{
	machine tsdp_machine_message;
	
	###########################################
	#	Includes
	###########################################
	include tsdp_machine_utils "./tsdp_machine_utils.jrl";
	
	action tag{
		i_tag_start = p;
	}

	###########################################
	#	Actions
	###########################################
	action parse_header_A{
		if(hdr_M){
			if((header = tsdp_header_A.prototype.Parse(tsk_ragel_parser_get_string(s_str, p, i_tag_start)))){
				hdr_M.ao_hdr_A.push(header);
			}
		}
		else if((header = tsdp_header_A.prototype.Parse(tsk_ragel_parser_get_string(s_str, p, i_tag_start)))){
			sdp_msg.add_header(header);
		}
	}

	action parse_header_B{
		if(hdr_M){
			if((header = tsdp_header_B.prototype.Parse(tsk_ragel_parser_get_string(s_str, p, i_tag_start)))){
				hdr_M.ao_hdr_B.push(header);
			}
		}
		else if((header = tsdp_header_B.prototype.Parse(tsk_ragel_parser_get_string(s_str, p, i_tag_start)))){
			sdp_msg.add_header(header);
		}
	}
	
	action parse_header_C{
		if(hdr_M && !hdr_M.o_hdr_C){
			hdr_M.o_hdr_C = tsdp_header_C.prototype.Parse(tsk_ragel_parser_get_string(s_str, p, i_tag_start));
		}
		else if((header = tsdp_header_C.prototype.Parse(tsk_ragel_parser_get_string(s_str, p, i_tag_start)))){
			sdp_msg.add_header(header);
		}
	}
	
	action parse_header_Dummy{
		if((header = tsdp_header_Dummy.prototype.Parse(tsk_ragel_parser_get_string(s_str, p, i_tag_start)))){
			if(hdr_M){
				hdr_M.ao_hdr_Dummy.push(header);
			}
			else{
				sdp_msg.add_header(header);
			}
		}
	}
	
	action parse_header_E{
		if((header = tsdp_header_E.prototype.Parse(tsk_ragel_parser_get_string(s_str, p, i_tag_start)))){
			sdp_msg.add_header(header);
		}
	}
	
	action parse_header_I{
		if(hdr_M && !hdr_M.o_hdr_I){
			hdr_M.o_hdr_I = tsdp_header_I.prototype.Parse(tsk_ragel_parser_get_string(s_str, p, i_tag_start));
		}
		else if((header = tsdp_header_I.prototype.Parse(tsk_ragel_parser_get_string(s_str, p, i_tag_start)))){
			sdp_msg.add_header(header);
		}
	}
	
	action parse_header_K{
		if(hdr_M && !hdr_M.o_hdr_K){
			hdr_M.o_hdr_K = tsdp_header_K.prototype.Parse(tsk_ragel_parser_get_string(s_str, p, i_tag_start));
		}
		else if((header = tsdp_header_K.prototype.Parse(tsk_ragel_parser_get_string(s_str, p, i_tag_start)))){
			sdp_msg.add_header(header);
		}
	}
	
	action parse_header_M{
		if((hdr_M = tsdp_header_M.prototype.Parse(tsk_ragel_parser_get_string(s_str, p, i_tag_start)))){
			sdp_msg.add_header(hdr_M);
		}
	}
	
	action parse_header_O{
		if((header = tsdp_header_O.prototype.Parse(tsk_ragel_parser_get_string(s_str, p, i_tag_start)))){
			sdp_msg.add_header(header);
		}
	}
	
	action parse_header_P{
		if((header = tsdp_header_P.prototype.Parse(tsk_ragel_parser_get_string(s_str, p, i_tag_start)))){
			sdp_msg.add_header(header);
		}
	}

	action parse_header_R{
		if((header = tsdp_header_R.prototype.Parse(tsk_ragel_parser_get_string(s_str, p, i_tag_start)))){
			if(hdr_T){
				hdr_T.ao_hdr_R.push(header);
			}
			else{
				sdp_msg.add_header(header);
			}
		}
	}
	
	action parse_header_S{
		if((header = tsdp_header_S.prototype.Parse(tsk_ragel_parser_get_string(s_str, p, i_tag_start)))){
			sdp_msg.add_header(header);
		}
	}
	
	action parse_header_T{
		if((hdr_T = tsdp_header_T.prototype.Parse(tsk_ragel_parser_get_string(s_str, p, i_tag_start)))){
			sdp_msg.add_header(hdr_T);
			hdr_T = null;
		}
	}

	action parse_header_U{
		if((header = tsdp_header_U.prototype.Parse(tsk_ragel_parser_get_string(s_str, p, i_tag_start)))){
			sdp_msg.add_header(header);
		}
	}

	action parse_header_V{
		if((header = tsdp_header_V.prototype.Parse(tsk_ragel_parser_get_string(s_str, p, i_tag_start)))){
			sdp_msg.add_header(header);
		}
	}

	action parse_header_Z{
		if((header = tsdp_header_Z.prototype.Parse(tsk_ragel_parser_get_string(s_str, p, i_tag_start)))){
			sdp_msg.add_header(header);
		}
	}

	###########################################
	#	Headers
	###########################################

	A = "a"i SP* "=" SP*<: js_any* %parse_header_A :>CRLF;
	B = "b"i SP* "=" SP*<: js_any* %parse_header_B :>CRLF;
	C = "c"i SP* "=" SP*<: js_any* %parse_header_C :>CRLF;
	E = "e"i SP* "=" SP*<: js_any* %parse_header_E :>CRLF;
	I = "i"i SP* "=" SP*<: js_any* %parse_header_I :>CRLF;
	K = "k"i SP* "=" SP*<: js_any* %parse_header_K :>CRLF;
	M = "m"i SP* "=" SP*<: js_any* %parse_header_M :>CRLF;
	O = "o"i SP* "=" SP*<: js_any* %parse_header_O :>CRLF;
	P = "p"i SP* "=" SP*<: js_any* %parse_header_P :>CRLF;
	R = "r"i SP* "=" SP*<: js_any* %parse_header_R :>CRLF;
	S = "s"i SP* "=" SP*<: js_any* %parse_header_S :>CRLF;
	T = "t"i SP* "=" SP*<: js_any* %parse_header_T :>CRLF;
	U = "u"i SP* "=" SP*<: js_any* %parse_header_U :>CRLF;
	V = "v"i SP* "=" SP*<: js_any* %parse_header_V :>CRLF;
	Z = "z"i SP* "=" SP*<: js_any* %parse_header_Z :>CRLF;

	Dummy = alpha SP* "=" SP*<: js_any* %parse_header_Dummy :>CRLF;

	Header = (A | B | C | E | I | K | M | O | P | R | S | T | U | V | Z)>tag >1 | (Dummy>tag) >0;


	###########################################
	#	Message
	###########################################
	SDP_message = Header*;

	###########################################
	#	Entry Point
	###########################################
	main := SDP_message;
}%%

/* Ragel data */
%% write data;

tsdp_message.prototype.Parse = function(s_str){
	var cs = 0;
	var p = 0;
	var pe = s_str.length;
	var eof = pe;
	var data = tsk_buff_str2ib(s_str);
	var i_tag_start;	
	var sdp_msg = new tsdp_message();
	var header = null;
	var hdr_T = null;
	var hdr_M = null;
	
	%%write init;
	%%write exec;
	
	if( cs < %%{ write first_final; }%% ){
		tsk_utils_log_error("Failed to parse sdp message: " + s_str);
		return null;
	}
	
	return sdp_msg;
}