'use strict';
'require baseclass';
'require fs';
'require rpc';
'require network';

var callSystemBoard = rpc.declare({
	object: 'system',
	method: 'board'
});

var callSystemInfo = rpc.declare({
	object: 'system',
	method: 'info'
});

return baseclass.extend({

	params: [],

	load() {
		return Promise.all([
			network.getWANNetworks(),
			network.getWAN6Networks(),
			L.resolveDefault(callSystemBoard(), {}),
			L.resolveDefault(callSystemInfo(), {})
		]);
	},

	renderRow(title, value, className = '', tag = 'p') {
		return E(tag, { 'class': 'mt-2' }, [
			E('span', {}, [ title + '：' ]),
			E('span', { 'class': className }, [ value ])
		]);
	},

	renderArrayAsTable(title, values) {
		const table = E('table', { 'class': 'table' });

		if (Array.isArray(values) && values.length > 0) {
			values.forEach((val) => {
				table.appendChild(E('tr', {}, [
					E('td', {}, [ title + '：' ]),
					E('td', {}, [ val ])
				]));
			});
		} else {
			table.appendChild(E('tr', {}, [
				E('td', {}, [ title + '：' ]),
				E('td', {}, [ '-' ])
			]));
		}

		return table;
	},

	renderHtml(data, type) {

		let icon = type;
		const title = 'router' == type ? _('System') : _('Internet');
		const container_wapper = E('div', { 'class': type + '-status-self dashboard-bg box-s1'});
		const container_box = E('div', { 'class': type + '-status-info'});
		const container_item = E('div', { 'class': 'settings-info'});

		if ('internet' == type) {
			icon = (data.v4.connected.value || data.v6.connected.value) ? type : 'not-internet';
		}

		container_box.appendChild(E('div', { 'class': 'title'}, [
			E('img', {
				'src': L.resource('view/dashboard/icons/' + icon + '.svg'),
				'width': 'router' == type ? 64 : 54,
				'title': title,
				'class': (type == 'router' || icon == 'not-internet') ? 'middle svgmonotone' : 'middle'
			}),
			E('h3', title)
		]));

		container_box.appendChild(E('hr'));

		if ('internet' == type) {
			const container_internet_v4 = E('div');
			const container_internet_v6 = E('div');

			for(let idx in data) {

				for(let ver in data[idx]) {
					let classname = ver;
					const visible = data[idx][ver].visible;

					if('connected' === ver) {
						classname = data[idx][ver].value ? 'label label-success' : 'label label-danger';
						data[idx][ver].value = data[idx][ver].value ? _('yes') : _('no');
					}

					if ('v4' === idx) {

						if ('title' === ver) {
							container_internet_v4.appendChild(
								E('p', { 'class': 'mt-2'}, [
									E('span', {'class': ''}, [ data[idx].title ]),
								])
							);
							continue;
						}

						if ('addrsv4' === ver) {
							const addrs = data[idx][ver].value;
							if(Array.isArray(addrs) && addrs.length) {
								for(let ip in addrs) {
									data[idx][ver].value = addrs[ip].split('/')[0];
								}
							}
						}

						if (visible) {
							if (['dnsv4'].includes(ver) && Array.isArray(data[idx][ver].value)) {
								container_internet_v4.appendChild(this.renderArrayAsTable(data[idx][ver].title, data[idx][ver].value));
							} else {
								container_internet_v4.appendChild(this.renderRow(data[idx][ver].title, data[idx][ver].value, classname));
							}
						}

					} else {

						if ('title' === ver) {
							container_internet_v6.appendChild(
								E('p', { 'class': 'mt-2'}, [
									E('span', {'class': ''}, [ data[idx].title ]),
								])
							);
							continue;
						}

						if (visible) {
							if (['dnsv6'].includes(ver) && Array.isArray(data[idx][ver].value)) {
								container_internet_v6.appendChild(this.renderArrayAsTable(data[idx][ver].title, data[idx][ver].value));
							} else {
								container_internet_v6.appendChild(this.renderRow(data[idx][ver].title, data[idx][ver].value, classname));
							}
						}
					}
				}
			}

			container_item.appendChild(container_internet_v4);
			container_item.appendChild(container_internet_v6);
		} else {
			for(let idx in data) {
				container_item.appendChild(
					E('p', { 'class': 'mt-2'}, [
						E('span', {'class': ''}, [ data[idx].title + '：' ]),
						E('span', {'class': ''}, [ data[idx].value ])
					])
				);
			}
		}

		container_box.appendChild(container_item);
		container_box.appendChild(E('hr'));
		container_wapper.appendChild(container_box);
		return container_wapper;
	},

	renderUpdateWanData(data, v6) {

		let min_metric = 2000000000;
		let min_metric_i = 0;
		for (let i = 0; i < data.length; i++) {
			const metric = data[i].getMetric();
			if (metric < min_metric) {
				min_metric = metric;
				min_metric_i = i;
			}
		 }

		const ifc = data[min_metric_i];
		if(ifc){
			if (v6) {
				const uptime = ifc.getUptime();
				this.params.internet.v6.uptime.value = (uptime > 0) ? '%t'.format(uptime) : '-';
				this.params.internet.v6.ipprefixv6.value =  ifc.getIP6Prefix() || '-';
				this.params.internet.v6.gatewayv6.value =  ifc.getGateway6Addr() || '-';
				this.params.internet.v6.protocol.value=  ifc.getI18n() || E('em', _('Not connected'));
				this.params.internet.v6.addrsv6.value = ifc.getIP6Addrs() || [ '-' ];
				this.params.internet.v6.dnsv6.value = ifc.getDNS6Addrs() || [ '-' ];
				this.params.internet.v6.connected.value = ifc.isUp();
			} else {
				const uptime = ifc.getUptime();
				this.params.internet.v4.uptime.value = (uptime > 0) ? '%t'.format(uptime) : '-';
				this.params.internet.v4.protocol.value=  ifc.getI18n() || E('em', _('Not connected'));
				this.params.internet.v4.gatewayv4.value =  ifc.getGatewayAddr() || '0.0.0.0';
				this.params.internet.v4.connected.value = ifc.isUp();
				this.params.internet.v4.addrsv4.value = ifc.getIPAddrs() || [ '-'];
				this.params.internet.v4.dnsv4.value = ifc.getDNSAddrs() || [ '-' ];
			}
		}
	},

	renderInternetBox(data) {

		this.params.internet = {

			v4: {
				title: _('IPv4 Internet'),

				connected: {
					title: _('Connected'),
					visible: true,
					value: false
				},

				uptime: {
					title: _('Uptime'),
					visible: true,
					value: '-'
				},

				protocol: {
					title: _('Protocol'),
					visible: true,
					value: '-'
				},

				addrsv4: {
					title: _('IPv4'),
					visible: true,
					value: [ '-' ]
				},

				gatewayv4: {
					title: _('GatewayV4'),
					visible: true,
					value: '-'
				},

				dnsv4: {
					title: _('DNSv4'),
					visible: true,
					value: ['-']
				}
			},

			v6: {
				title: _('IPv6 Internet'),

				connected: {
					title: _('Connected'),
					visible: true,
					value: false
				},

				uptime: {
					title: _('Uptime'),
					visible: true,
					value: '-'
				},

				protocol: {
					title: _('Protocol'),
					visible: true,
					value: ' - '
				},

				ipprefixv6 : {
					title: _('IPv6 prefix'),
					visible: true,
					value: ' - '
				},

				addrsv6: {
					title: _('IPv6'),
					visible: false,
					value: [ '-' ]
				},

				gatewayv6: {
					title: _('GatewayV6'),
					visible: true,
					value: '-'
				},

				dnsv6: {
					title: _('DNSv6'),
					visible: true,
					value: [ '-' ]
				}
			}
		};

		this.renderUpdateWanData(data[0], false);
		this.renderUpdateWanData(data[1], true);

		return this.renderHtml(this.params.internet, 'internet');
	},

	renderRouterBox(data) {

		const boardinfo   = data[2];
		const systeminfo  = data[3];

		let datestr = null;

		if (systeminfo.localtime) {
			const date = new Date(systeminfo.localtime * 1000);

			datestr = '%04d-%02d-%02d %02d:%02d:%02d'.format(
				date.getUTCFullYear(),
				date.getUTCMonth() + 1,
				date.getUTCDate(),
				date.getUTCHours(),
				date.getUTCMinutes(),
				date.getUTCSeconds()
			);
		}

		this.params.router = {
			uptime: {
				title: _('Uptime'),
				value: systeminfo.uptime ? '%t'.format(systeminfo.uptime) : null,
			},

			localtime: {
				title: _('Local Time'),
				value: datestr
			},

			kernel: {
				title: _('Kernel Version'),
				value: boardinfo.kernel
			},

			model: {
				title: _('Model'),
				value: boardinfo.model
			},

			system: {
				title: _('Architecture'),
				value: boardinfo.system
			},

			release: {
				title: _('Firmware Version'),
				value: boardinfo?.release?.description
			}
		};

		return this.renderHtml(this.params.router, 'router');
	},

	render(data) {
		return [this.renderInternetBox(data), this.renderRouterBox(data)];
	}
});
