<%#
 Copyright 2018 Rosy Song <rosysong@rosinson.com>
 Licensed to the public under the Apache License 2.0.
-%>

<%+header%>

<script>
	var bwxhr = new XHR();

	var RC = { };
	var em = 0;
	var ec = 1;

	var rate_table_dl;
	var rate_table_ul;

	function init_bytes(rl, ra) {
		var bytes_pre;
		var obj = { };
		obj.chain = rl.chain;
		obj.ipaddr = rl.expr[em].match.right;
		obj.bytes = rl.expr[ec].counter.bytes;
		obj.packets = rl.expr[ec].counter.packets;
		obj.rate = 0;

		if (RC[obj.chain] && RC[obj.chain][obj.ipaddr])
				bytes_pre = RC[obj.chain][obj.ipaddr];
		else
				bytes_pre = 0;

		obj.rate = (bytes_pre > 0) ? (obj.bytes - bytes_pre) / 3: 0;

		if (!RC[obj.chain])
				RC[obj.chain] = { };
		RC[obj.chain][obj.ipaddr] = obj.bytes;

		if (!ra[obj.chain])
				ra[obj.chain] = [ ];
		ra[obj.chain].push(obj);
	} /* function init_bytes(rl, ra) */

	function bytes_label(bytes) {
		var uby = '<%:kB%>';
		var kby = (bytes / 1024);

		if (kby > 1024) {
			uby = '<%:MB%>';
			kby = (kby / 1024);
		}

		return String.format("%f %s", kby.toFixed(2), uby);
	}

	function print_table(tbl, rs, ra) {
		ra.sort(function(a, b) { return b.rate - a.rate });
		for (var i = 0; i < ra.length; i++) {
			rs.push([
				ra[i].ipaddr,
				bytes_label(ra[i].rate) + '/s',
				bytes_label(ra[i].bytes),
				'%s Pkts.'.format(ra[i].packets),
			]);
		}
		cbi_update_table(tbl, rs, '<em><%:No information available%></em>');
	} /* function print_table(tbl, ra) */

	/* wait for SVG */
	window.setTimeout(
		function() {
			if (!RC)
			{
				window.setTimeout(arguments.callee, 1000);
			}
			else
			{
				rate_table_dl     = document.getElementById('rate_table_dl');
				rate_table_ul     = document.getElementById('rate_table_ul');

				/* render datasets, start update interval */
				XHR.poll(3, '<%=build_url("admin/status/realtime/rate_status")%>', null,
					function(x, json)
					{
						var RA = {};
						var rows_dl = [];
						var rows_ul = [];

						var rules = json.nftables;
						for (var i = 0; i < rules.length; i++)
						{
							if (!rules[i].rule)
								continue;
							if (rules[i].rule.table != 'nft-qos-monitor')
								continue;

							var rl = rules[i].rule;
							switch (rl.chain)
							{
								case 'download':
								case 'upload': init_bytes(rl, RA); break;
							}
						} /* for (var i = 0; i < rules.length; i++) */

						/* display the result */
						if (RA.download) {
							while (rate_table_dl.firstElementChild !== rate_table_dl.lastElementChild)
								rate_table_dl.removeChild(rate_table_dl.lastElementChild);
							print_table(rate_table_dl, rows_dl, RA.download);
						}
						if (RA.upload) {
							while (rate_table_ul.firstElementChild !== rate_table_ul.lastElementChild)
								rate_table_ul.removeChild(rate_table_ul.lastElementChild);
							print_table(rate_table_ul, rows_ul, RA.upload);
						}

					} /* function(x, json) */
				); /* XHR.poll() */

				XHR.run();
			}
		}, 1000
	);
</script>

<h2 name="content"><%:Realtime Rate%></h2>

<div class="cbi-map-descr"><%:This page gives an overview over currently download/upload rate.%></div>

<fieldset class="cbi-section" id="cbi-table-table">
	<legend><%:Realtime Download Rate%></legend>
	<div class="cbi-section-node">
		<div class="table" id="rate_table_dl">
			<div class="tr table-titles">
				<div class="th col-2 hide-xs"><%:IP Address%></div>
				<div class="th col-2"><%:Download Rate%></div>
				<div class="th col-7"><%:Bytes Total%></div>
				<div class="th col-7"><%:Packets Total%></div>
			</div>
			<div class="tr placeholder">
				<div class="td">
					<em><%:Collecting data...%></em>
				</div>
			</div>
		</div>
	</div>
</fieldset>

<fieldset class="cbi-section" id="cbi-table-table">
	<legend><%:Realtime Upload Rate%></legend>
	<div class="cbi-section-node">
		<div class="table" id="rate_table_ul">
			<div class="tr table-titles">
				<div class="th col-2 hide-xs"><%:IP Address%></div>
				<div class="th col-2"><%:Upload Rate%></div>
				<div class="th col-7"><%:Bytes Total%></div>
				<div class="th col-7"><%:Packets Total%></div>
			</div>
			<div class="tr placeholder">
				<div class="td">
					<em><%:Collecting data...%></em>
				</div>
			</div>
		</div>
	</div>
</fieldset>

<%+footer%>
