namespace _heimdall.check_kinds.generic_remote
{
	
	/**
	 */
	function parameters_schema(
	) : _heimdall.helpers.json_schema.type_schema
	{
		return {
			"type": "object",
			"additionalProperties": false,
			"properties": {
				"host" : {
					"type" : "string"
				},
				"ssh_port": {
					"anyOf": [
						{
							"type": "null",
							"default": null
						},
						{
							"type": "integer",
							"default": null
						},
					]
				},
				"ssh_user" : {
					"anyOf": [
						{
							"type": "null",
							"default": null
						},
						{
							"type": "integer",
							"default": null
						},
					]
				},
				"ssh_key" : {
					"anyOf": [
						{
							"type": "null",
							"default": null
						},
						{
							"type": "integer",
							"default": null
						},
					]
				},
				"mount_point" : {
					"type" : "string",
					"default" : "/"
				},
				"threshold" : {
					"type" : "integer",
					"default" : 95,
					"description" : "maximaler Füllstand in Prozent"
				},
				"critical": {
					"description": "whether a violation of this check shall be leveled as critical instead of concerning",
					"type": "boolean",
					"default": true
				},
				"strict": {
					"deprecated": true,
					"description": "alias for 'critical'",
					"type": "boolean",
					"default": true
				},
			},
			"required": [
				"host",
			]
		};
	}
	
	
	/**
	 */
	function normalize_order_node(
		node : any
	) : any
	{
		const version : string = (
			(! ("critical" in node))
			? "v1"
			: "v2"
		);
		switch (version) {
			default: {
				throw (new Error("unhandled version"));
				break;
			}
			case "v1": {
				if (! ("host" in node)) {
					throw (new Error("mandatory parameter \"host\" missing"));
				}
				else {
					const node_ = lib_plankton.object.patched(
						{
							"ssh_port": null,
							"ssh_user": null,
							"ssh_key": null,
							"mount_point": "/",
							"threshold": 95,
							"strict": false,
						},
						node,
						true
					);
					return {
						"host": node_["host"],
						"ssh_port": node_["ssh_port"],
						"ssh_user": node_["ssh_user"],
						"ssh_key": node_["ssh_key"],
						"mount_point": node_["mount_point"],
						"threshold": node_["threshold"],
						"critical": node_["strict"],
					};
				}
				break;
			}
			case "v2": {
				if (! ("host" in node)) {
					throw (new Error("mandatory parameter \"host\" missing"));
				}
				else {
					const node_ = lib_plankton.object.patched(
						{
							"ssh_port": null,
							"ssh_user": null,
							"ssh_key": null,
							"mount_point": "/",
							"threshold": 95,
							"critical": false,
						},
						node,
						true
					);
					return node_;
				}
				break;
			}
		}
	}
	
	
	/**
	 */
	async function run(
		parameters
	) : Promise<_heimdall.type_result>
	{
		const nm_child_process = require("child_process");
		
		const inner_command : string = lib_plankton.string.coin(
			"df {{mount_point}} | tr -s \" \"",
			{
				"mount_point": parameters["mount_point"],
			}
		);
		
		let outer_command_parts : Array<string> = [];
		if (true) {
			outer_command_parts.push("ssh");
		}
		if (true) {
			outer_command_parts.push(lib_plankton.string.coin("{{host}}", {"host": parameters["host"]}));
		}
		if (parameters["ssh_port"] !== null) {
			outer_command_parts.push(lib_plankton.string.coin("-p", {}));
			outer_command_parts.push(lib_plankton.string.coin("{{port}}", {"port": parameters["ssh_port"].toFixed(0)}));
		}
		if (parameters["ssh_user"] !== null) {
			outer_command_parts.push(lib_plankton.string.coin("-l", {}));
			outer_command_parts.push(lib_plankton.string.coin("{{user}}", {"user": parameters["ssh_user"]}));
		}
		if (parameters["ssh_key"] !== null) {
			outer_command_parts.push(lib_plankton.string.coin("-i", {}));
			outer_command_parts.push(lib_plankton.string.coin("{{key}}", {"key": parameters["ssh_key"]}));
		}
		if (true) {
			outer_command_parts.push(lib_plankton.string.coin("-o", {}));
			outer_command_parts.push(lib_plankton.string.coin("BatchMode=yes", {}));
		}
		if (true) {
			outer_command_parts.push(lib_plankton.string.coin("{{inner_command}}", {"inner_command": inner_command}));
		}
		const outer_command : string = outer_command_parts.join(" ");
		
		const shell_exec_result : _heimdall.helpers.misc.type_shell_exec_result = await _heimdall.helpers.misc.shell_exec(
			outer_command_parts[0],
			outer_command_parts.slice(1)
		);
		
		if (shell_exec_result.return_code > 0) {
			return {
				"condition": _heimdall.enum_condition.unknown,
				"info": {
					"command": outer_command,
					"error": shell_exec_result.stderr,
				}
			};
		}
		else {
			const stuff : Array<string> = shell_exec_result.stdout.split("\n").slice(-2)[0].split(" ");
			const data = {
				"device": stuff[0],
				"used": parseInt(stuff[2]),
				"avail": parseInt(stuff[3]),
				"perc": parseInt(stuff[4].slice(-1)),
			};
			let faults : Array<string> = [];
			if (data["perc"] > parameters["threshold"]) {
				faults.push(lib_plankton.translate.get("checks.generic_remote.overflow"));
			}
			else {
				// do nothing
			}
			return {
				"condition": (
					(faults.length <= 0)
					? _heimdall.enum_condition.ok
					: (
						parameters["critical"]
						? _heimdall.enum_condition.critical
						: _heimdall.enum_condition.concerning
					)
				),
				"info": {
					"data": {
						"host": parameters["host"],
						"device": data["device"],
						"mount_point": parameters["mount_point"],
						"used": _heimdall.helpers.misc.format_bytes(data["used"]),
						"available": _heimdall.helpers.misc.format_bytes(data["avail"]),
						"percentage": (data["perc"].toFixed(0) + "%"),
					},
					"faults": faults,
				},
			};
		}
	}
	
	
	/**
	 */
	register_implementation(
		"generic_remote",
		{
			"parameters_schema": parameters_schema,
			"normalize_order_node": normalize_order_node,
			"run": run,
		}
	);
	
}
