<%#
Opennet Firmware

Copyright 2010 Rene Ejury <opennet@absorb.it>
Copyright 2014 Lars Kruse <devel@sumpfralle.de>

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

	http://www.apache.org/licenses/LICENSE-2.0

-%>

<%
	require("luci.model.opennet.funcs")
	local sorting = on_function("get_service_sorting")
%>

<%+header%>

<!-- erforderlich fuer "String.format" -->
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<script type="text/javascript">//<![CDATA[

	// **************** asynchrone Abfrage der Gateway-Details *********************

	// wir moechten einen Hinweis ausgeben, falls ein Sprung vom aktuellen Gateway auf einen besseren Gateway bevorsteht
	var best_gateway;
	var current_gateway;
	var service_dict = {};

	// loese die Anfrage nach allen Dienst-IDs aus - diese werden anschliessend einzeln nacheinander abgefragt
	XHR.get('<%=luci.dispatcher.build_url("opennet", "opennet_2", "vpn_gateway_list")%>', null, build_table);

	function build_table(dummy, services) {
		// splitte die Liste der Dienste in mehrere parallele Ablaeufe
		// ein Wert groesser als drei scheint keine Beschleunigung zu bringen (mit einem TL-WDR4300)
		var RUN_IN_PARALLEL = 2;
		var result = "";
		var target_table = document.getElementById('on-gateway-list');
		var in_progress_spinner = document.getElementById('gateway-list-spinner');
		if (!target_table) return;
		// Tabellenzeilen erzeugen
		for (var index = 0; index < services.length; index++) {
			result += String.format('<tr id="%s" class="cbi-section-table-row cbi-opennet-gateways" disabled="n">', services[index]);
			result += String.format('<td class="cbi-value-field"><div id="cbi-opennet-gateways-count">%d</div></td>', index + 1);
			result += '</tr>';
			service_dict[services[index]] = index;
		}
		// die letzte Zeile unter der Tabelle einfuegen (z.B. fuer "reset counter")
		result += '<tr id="cbi-opennet-gateways" class="cbi-section-table-row">'
			+ '	<td colspan="5" />'
			+ '	<td class="cbi-value-field"><input class="cbi-button" type="submit" name="reset_connection_test_timestamps" value="<%:reset test counter%>" /></td>'
			+ '	<td />'
			+ '</tr>';
		target_table.innerHTML += result;
		// Aktivitaetsindikator verstecken
		if (in_progress_spinner) in_progress_spinner.style.display = 'none';
		// die Anfragen in parallelen Wellen ausloesen
		var parallels = [];
		// Listen vorbereiten
		while (parallels.length < RUN_IN_PARALLEL) parallels.push([]);
		parallels = services.reduce(function(list, current, index) {
				list[index % RUN_IN_PARALLEL].push(current);
				return list;
			}, parallels);
		for (var index = 0; index < parallels.length; index++) {
			schedule_next_service(parallels[index]);
		};
	}

	function schedule_next_service(remaining_services) {
		if (remaining_services && (remaining_services.length > 0)) {
			XHR.get('<%=luci.dispatcher.build_url("opennet", "opennet_2", "vpn_gateway_info")%>/' + remaining_services[0], null,
				function(x, info) { if (info) { insert_gateway(info, remaining_services.slice(1)); }});
		}
	}

	function insert_gateway(gateway, remaining_services) {
		// Fuege eine neue Tabellenzeile ein
		var target_row = document.getElementById(gateway.id);
		if (!target_row) return;
		var remote;
		var active;
		var distance;
		var speed;
		var speed_abbr;
		var result = "";
		// "remote" menschenfreundlich setzen
		remote = gateway.host;
		if (gateway.port != 1600) {
			remote += ":" + (gateway.port || "?");
		}
		// "active" als laeuft/kaputt/inaktive setzen
		if (gateway.active) {
			current_gateway = gateway.id;
			update_gateway_change_indicator();
			<% if nixio.fs.access("/tmp/openvpn_msg.txt") then %>
				active = "y";
			<% else %>
				active="n";
			<% end %>
		} else {
			active = null;
		}
		// best_gateway setzen, falls noch ungesetzt oder weiter oben, als der bisher beste
		if ((gateway.status == "y") && !gateway.disabled
				&& (!best_gateway || (service_dict[best_gateway] > service_dict[gateway.id]))) {
			best_gateway = gateway.id;
			update_gateway_change_indicator();
		}
		result += String.format('<td class="cbi-value-field"><div id="cbi-opennet-gateways-active" active="%s">&nbsp;</div>', active);
		result += String.format('<td><strong>%s</strong></th>', remote);
		// wir zeigen die Rang-Zahlen fuer Dienste nicht an
		if ("<%=sorting%>" != "manual") {
			result += '<td class="cbi-value-field"><div id="cbi-opennet-gateways-hopcount">';
			if (gateway.distance && (gateway.offset != 0)) {
				result += String.format('(%d)<input class="cbi-button cbi-button-clear cbi-button-small" type="submit" value="%s" title="<%:reset offset%>" name="reset_offset" />', gateway.offset, gateway.id, gateway);
			}
			<% if sorting == "etx" then %>
				distance = gateway.distance;
			<% elseif sorting == "hop" then %>
				distance = gateway.hop_count;
			<% end %>
			result += String.format('%s</div></td>', distance);
		}
		result += '<td>';
		if (gateway.upload || gateway.download) {
			speed = String.format('%s kbps / %s kbps', gateway.upload || "?", gateway.download || "?");
			speed_abbr = String.format('<%:upload to Internet %s kbit/s; download from Internet %s kbit/s%>', gateway.upload || "?", gateway.download || "?");
			result += String.format('<div class="vpn-wan-speed" name="speed" id="cbi-opennet-gateways-speed" ><abbr title="%s">%s</abbr></div>', speed_abbr, speed);
		}
		result += '</td>';
		result += String.format('<td class="cbi-value-field" title="<%:tested %d minutes ago%>"><div id="cbi-opennet-gateways-status" status="%s">&nbsp;</div></td>', gateway.age, gateway.status);
		result += '<td class="cbi-value-field"><div id="cbi-opennet-gateways-actions">';
		if (gateway.disabled) {
			target_row.setAttribute("disabled", "y");
			result += String.format('<input class="cbi-button cbi-button-enable cbi-button-small" type="submit" value="%s" title="<%:enable%>" name="enable_service" />', gateway.id);
		} else {
			result += String.format('<input class="cbi-button cbi-button-top cbi-button-small" type="submit" value="%s" title="<%:move to top and connect immediately%>" name="move_top" />', gateway.id);
			result += String.format('<input class="cbi-button cbi-button-up cbi-button-small" type="submit" value="%s" title="<%:move up%>" name="move_up" />', gateway.id);
			result += String.format('<input class="cbi-button cbi-button-down cbi-button-small" type="submit" value="%s" title="<%:move down%>" name="move_down" />', gateway.id);
			result += String.format('<input class="cbi-button cbi-button-del cbi-button-small" type="submit" value="%s" title="<%:delete%>" name="delete_service" />', gateway.id);
			result += String.format('<input class="cbi-button cbi-button-disable cbi-button-small" type="submit" value="%s" title="<%:disable%>" name="disable_service" />', gateway.id);
		}
		result += '</div></tr>';
		target_row.innerHTML += result;
		// loese die naechste Anfrage aus (falls weitere vorhanden sind)
		// Wir sollten diese Anfrage nicht frueher ausloesen, weil beispielsweise die
		// letzte Zeile ("add_table_footer") sonst hochrutscht (sie ist zu schnell abgeschlossen).
		schedule_next_service(remaining_services);
	}

	// ausserdem wird die Nachricht "Gateway-Wechsel steht bevor" ausgegeben
	function update_gateway_change_indicator() {
		var change_label = document.getElementById('on-waiting-for-gateway-change');
		if (change_label && current_gateway && best_gateway) {
			if (current_gateway != best_gateway) {
				change_label.style.display = 'block';
			} else {
				change_label.style.display = 'none';
			}
		}
	}

//]]></script>

<h2><a id="content" name="content"><%:Opennet OpenVPN Gateways%></a></h2>
<div class="cbi-map">
	<fieldset class="cbi-section">
		<div class="cbi-value-comment">
			<p><%:Here you can configure the IP-Addresses of your choosen Gateways.%></p>
			<% if show_more_info then %>
				<p><%:Take a look at the Opennet wiki, if you would like to know more about the Gateway system. Usually the first found Gateway in your list is the one you are going to use. The Gateway will be changed automatically, if the current Gateway does not work for approximately 120 seconds.%></p>
				<p><%:Your router periodically tries to connect to all available Gateways in the Opennet network. The results of these tests are indicated in the "Status" column below.%></p>
				<p><%:The "distance" column indicates the routing distance to this Gateway. The selection of your preferred gateway is based on this value.%></p>
				<p><%:Additionally you may choose to rank specific gateways higher or lower than their routing distance would indicate. Please be careful with this manual intervention since it could force your connection through an inefficient path. Usually you should just keep the default values.%></p>
				<p><%:If you notice a severe slow-down of your connection, you should try to remove your manual priorities first. Use the small "clear" icon in the "offset/distance" column for this purpose.%></p>
			<% else %>
				<form method="post" action="<%=REQUEST_URI%>">
					<input type="submit" name="show_more_info" class="cbi-button-plain" value="<%:...more Information...%>" />
				</form>
			<% end %>
		</div>
	</fieldset>
</div>

<h3><%:Gateway-List%></h3>
	<div class="cbi-map">
		<fieldset class="cbi-section">
			<fieldset class="cbi-section-node">
				<form name="gateways" method="post" action="<%=REQUEST_URI%>">
				<table class="cbi-section-table" id="on-gateway-list">
				<tr class="cbi-section-table-titles">
						<th colspan = "1" />
						<th class="cbi-section-table-cell"><%:active%></th>
						<th class="cbi-section-table-cell"><%:IP-Address%></th>
						<% if sorting ~= "manual" then %>
							<th class="cbi-section-table-cell">
							<abbr title="<%:This offset is added to the values before use/display%>">Offset</abbr> /
							<% if sorting == "hop" then %>
								<abbr title="<%:Number of Hops to the Gateway%>"><%:Distance%></abbr>
							<% else %>
								<abbr title="<%:Expected Transmission Count - Quality of the Connection to the Gateway regarding OLSR%>"><%:ETX%></abbr>
							<% end %>
							</th>
						<% end %>

						<th class="cbi-section-table-cell"><abbr title="<%:Announced Upload / Download Speed.%>"><%:Speed%></abbr></th>

						<th class="cbi-section-table-cell"><%:VPN-Status%></th>
						<th class="cbi-section-table-cell"><%:Actions%></th>
						<th />
				</tr>

				</table>
				</form>
				<center><img class='loading_img_small' id="gateway-list-spinner" src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" /></center>
				<p id="on-waiting-for-gateway-change" style="display:none">
					<%:The first reachable Gateway is currently not in use. The Tunnel will be restarted and the Gateway will be changed in a few minutes. This change will be shown after a reload of this page.%>
				</p>
			</fieldset>
		</fieldset>
	</div>

	<% local gateway_log = luci.sys.exec("on-function get_mig_connection_log | tail -n 30 | tac") %>
	<% if gateway_log ~= "" then %>
		<h3><%:Connection log%></h3>
		<!-- Verbindungslog -->
		<div class="cbi-map"><fieldset class="cbi-section">
			<textarea xmlns="http://www.w3.org/1999/xhtml" readonly="readonly" rows="10" cols="110" wrap="off"><%=gateway_log%></textarea>
		</fieldset></div>
	<% end %>
<%+footer%>
