module HTTP_Adapter {

/* HTTP Adapter component, originally part of Integration Tests for osmo-remsim-server
 * (C) 2019 by Harald Welte <laforge@gnumonks.org>
 * All rights reserved.
 *
 * Released under the terms of GNU General Public License, Version 2 or
 * (at your option) any later version.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 *
 * This test suite tests osmo-remsim-server by attaching to the external interfaces
 * such as RSPRO for simulated clients + bankds and RSRES (REST backend interface).
 */

import from HTTPmsg_Types all;
import from HTTPmsg_PortType all;
import from Native_Functions all;

type component http_CT {
	port HTTPmsg_PT HTTP;
	var HTTP_Adapter_Params g_pars;
};

type record HTTP_Adapter_Params {
	charstring http_host,
	integer http_port,
	boolean use_ssl
};

function f_http_init(HTTP_Adapter_Params pars) runs on http_CT {
	map(self:HTTP, system:HTTP);
	g_pars := pars;
}

template (value) Connect ts_HTTP_Connect(template (value) charstring hostname,
					 template (value) integer http_port := 80,
					 template (value) boolean use_ssl := false) := {
	hostname := hostname,
	portnumber := http_port,
	use_ssl := use_ssl
}
template (value) Close ts_HTTP_Close := { client_id := omit };

/* function to add HeaderLines to a an existing set of HeaderLines. HeaderLines that are already present, are updated. */
function f_overlay_HTTP_Header(HeaderLines hdr, HeaderLines additional_hdr) return template (value) HeaderLines
{
	var integer i;
	var integer k;
	var boolean updated;

	for (i := 0; i < lengthof(additional_hdr); i := i+1) {
		updated := false;
		for (k := 0; k < lengthof(hdr); k := k+1) {
			if (f_str_tolower(hdr[k].header_name) == f_str_tolower(additional_hdr[i].header_name)) {
				hdr[k] := additional_hdr[i];
				updated := true;
			}
		}
		if (updated == false) {
			hdr := hdr & { additional_hdr[i] };
		}
	}

	return hdr;
}

template (value) HeaderLine ts_HeaderLine(charstring header_name, charstring header_value) := {
	header_name := header_name,
	header_value := header_value
}

function f_ts_HTTP_Header(template (omit) charstring body := omit,
			  template (omit) charstring host := omit,
			  HeaderLines custom_hdr := { })
return template (value) HeaderLines {
	var HeaderLines hdr := { };

	/* Build default header */
	if (not istemplatekind(host, "omit")) {
		hdr := hdr & {valueof(ts_HeaderLine("Host", valueof(host)))};
	}
	hdr := hdr & {{ header_name := "Content-Type", header_value := "application/json" }};
	if (not istemplatekind(body, "omit")) {
		hdr := hdr & {valueof(ts_HeaderLine("Content-Length", int2str(lengthof(body))))};
	}

	return f_overlay_HTTP_Header(hdr, custom_hdr);
}

function f_ts_body_or_empty(template (omit) charstring body) return template (value) charstring {
	if (istemplatekind(body, "omit")) {
		return "";
	}
	return body;
}

template (value) HTTPMessage ts_HTTP_Req(charstring url,
					 charstring method := "GET",
					 template (omit) charstring body := omit,
					 integer v_maj := 1, integer v_min := 1,
					 charstring host,
					 HeaderLines custom_hdr := { }) := {
	request := {
		client_id := omit,
		method := method,
		uri := url,
		version_major := v_maj,
		version_minor := v_min,
		header := f_ts_HTTP_Header(body, host, custom_hdr),
		body := f_ts_body_or_empty(body)
	}
}

template HTTPMessage tr_HTTP_Resp(template integer sts := ?) := {
	response := {
		client_id := ?,
		version_major := ?,
		version_minor := ?,
		statuscode := sts,
		statustext := ?,
		header := ?,
		body := ?
	}
};

template HTTPMessage tr_HTTP_Resp2xx := tr_HTTP_Resp((200..299));

function f_http_tx_request(charstring url, charstring method := "GET", template charstring body := omit,
			   HeaderLines custom_hdr := { })
runs on http_CT {
	HTTP.send(ts_HTTP_Connect(g_pars.http_host, g_pars.http_port, g_pars.use_ssl));
	HTTP.receive(Connect_result:?);
	HTTP.send(ts_HTTP_Req(url, method, body, host := g_pars.http_host & ":" & int2str(g_pars.http_port), custom_hdr := custom_hdr));
}

function f_http_rx_response(template HTTPMessage exp := tr_HTTP_Resp2xx, float tout := 2.0)
runs on http_CT return HTTPMessage {
	var HTTPMessage resp;
	timer T := tout;
	T.start;
	alt {
	[] HTTP.receive(exp) -> value resp {
		setverdict(pass);
		}
	[] HTTP.receive(tr_HTTP_Resp) -> value resp {
		setverdict(fail, "Unexpected HTTP response ", resp);
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for HTTP response");
		self.stop;
		}
	}
	HTTP.send(ts_HTTP_Close);
	return resp;
}

/* run a HTTP request and return the response */
function f_http_transact(charstring url, charstring method := "GET",
			 template (omit) charstring body := omit, template HTTPMessage exp := tr_HTTP_Resp2xx,
			 float tout := 2.0, HeaderLines custom_hdr := { })
runs on http_CT return HTTPMessage {
	f_http_tx_request(url, method, body, custom_hdr);
	return f_http_rx_response(exp, tout);
}

}
