/*
 * This file is part of the Companion project
 * Copyright (c) 2018 Bitfocus AS
 * Authors: William Viker <william@bitfocus.io>, Håkon Nessjøen <haakon@bitfocus.io>
 *
 * This program is free software.
 * You should have received a copy of the MIT licence as well as the Bitfocus
 * Individual Contributor License Agreement for companion along with
 * this program.
 *
 * You can be released from the requirements of the license by purchasing
 * a commercial license. Buying such a license is mandatory as soon as you
 * develop commercial activities involving the Companion software without
 * disclosing the source code of your own applications.
 *
 */

var debug    = require('debug')('lib/Interface/HelpHandler');
var CoreBase = require('../Core/Base');
var fs       = require('fs');
var marked   = require('marked');

class InterfaceHelpHandler extends CoreBase {

	constructor(registry) {
		super(registry, 'help');

		this.system.on('http_req', this.processHttpRequest.bind(this));

		this.system.on('io_connect', (client) => {
			client.on('get_help', (req) => {
				client.emit('get_help:result', this.getHelp(req));
			});
		});
	}

	/**
	 * Reads the Markdown file located in /documentation and returns it as HTML.
	 * 
	 * @param markdownFilename
	 */
	getDocumentationFile(markdownFilename) {

		// Prevent directory traversal
		markdownFilename = markdownFilename.replace(/(\.\.|\/)/g, '');
		var path = this.registry.getAppRoot() + '/documentation/' + markdownFilename;

		if (fs.existsSync(path)) {
			try {
				var help = fs.readFileSync(path);

				help = marked(help.toString(), {
					baseUrl      : '/int/documentation/',
					headerPrefix : 'header-',
				});

				return help;
			}
			catch (e) {
				debug('Error loading help ' + path);
				debug(e);
			}
		}

		return null;
	}

	getHelp(req) {
		// Return the rendered HTML for the requested Markdown file.
		// req will look like { file:'file.md' }.

		// Pass the filename requested back to the response so the receiver can watch for
		//  their response in case two different requests were made at the same time.
		var resp = {
			error : true,
			file  : req.file,
			html  : '',
		};

		if (req.file !== undefined) {
			var html;

			if ((html = this.getDocumentationFile(req.file)) !== null) {
				resp.error = false;
				resp.html  = html;
			}
		}
		else {
			debug('Invalid get_help request');
		}

		return resp;
	}

	processHttpRequest(req, res, done) {
		// Watch for HTTP requests made to /int/ (which emits 'http_req').
		var match;

		// Return any asset made to /int/documentation/
		if (match = req.url.match(/^\/documentation\/(.+?)(\?.+)?$/)) {
			var path = this.registry.getAppRoot() + '/documentation';
			var file = match[1].replace(/\.\.+/g, '');

			if (file.match(/\.(jpe?g|gif|png|pdf)$/) && fs.existsSync(path +'/'+ file)) {

				if (done !== undefined && typeof done == 'function') {
					done();
				}

				res.sendFile(path +'/'+ file);
			}
		}
		else if (match = req.url.match(/^\/help\/([^/]+)\/(.+?)(\?.+)?$/)) {
			var path = this.registry.getAppRoot() + '/lib/module';
			var module = match[1].replace(/\.\.+/g,'');
			var file = match[2].replace(/\.\.+/g,'');

			if (file.match(/\.(jpe?g|gif|png|pdf)$/) && fs.existsSync(path +'/'+ module + '/' + file)) {
				done();
				res.sendFile(path +'/'+ module + '/' + file);
			}
		}
	}
}

exports = module.exports = InterfaceHelpHandler;