var BaseValidator = require('libresignage/ui/validator/BaseValidator');

/**
* @typedef {object} FileSelectorValidatorSettings
*
* @property {string[]}          mimes    An array of accepted MIME types.
* @property {number}            name_len Maximum allowed filename length.
* @property {RegExp}            regex    "Whitelist" regex for filenames.
* @property {number}            minfiles Minimum number of selected files.
* @property {function|string[]} bl       A list of filenames to disallow. If a
*                                        function is provided, it should return
*                                        an array.
*
* @memberof module:libresignage/ui/validator
* @alias    FileSelectorValidatorSettings
*/

/**
* Class for validating inputs against a blacklist.
*
* @memberof module:libresignage/ui/validator
*/
class FileSelectorValidator extends BaseValidator {
	/**
	* Construct a new FileSelectorValidator object.
	*
	* @param {FileSelectorValidatorSettings} settings
	* @param {string}                        msg
	* @param {boolean}                       nostyle
	*
	* @see {@link module:libresignage/ui/validator.BaseValidator} Parent class.
	*/
	constructor(...args) {
		super(...args);
		this.chk_settings(
			['mimes', 'name_len', 'regex', 'minfiles', 'bl']
		);
	}

	validate(element) {
		let bl;
		let ftypes = [];
		let {name_len, regex, minfiles} = this.settings;

		/*
		* Parse file types from MIMEs. Direct MIME type comparison
		* is not used because Chrome (Chromium) doesn't report
		* local file MIME types correctly for at least video/ogg
		* (audio/ogg is reported instead).
		*
		* See: https://bugs.chromium.org/p/chromium/issues/detail?id=579915
		*/
		if (this.settings.mimes != null) {
			for (let k of Object.keys(this.settings.mimes)) {
				ftypes.push(this.settings.mimes[k].split('/')[1]);
			}
		} else {
			ftypes = null;
		}

		if (typeof this.settings.bl === 'function') {
			bl = this.settings.bl();
		} else {
			bl = this.settings.bl;
		}

		if (minfiles != null && element.files.length < minfiles) {
			return false;
		}

		for (let i = 0; i < element.files.length; i++) {
			if (
				(
					name_len != null
					&& element.files.item(i).name.length > name_len
				) || (
					ftypes != null
					&& !ftypes.includes(element.files.item(i).type.split('/')[1])
				) || (
					regex != null
					&& !element.files.item(i).name.match(regex)
				) || (
					bl != null
					&& bl.length != 0
					&& bl.includes(element.files.item(i).name)
				)
			) {
				return false;
			}
		}
		return true;
	}
}
module.exports = FileSelectorValidator;
