'use strict';
var path = require('path');
var fs = require('fs-path');
var glob = require('glob');
var AxeBuilder = require('axe-webdriverjs');
var WebDriver = require('selenium-webdriver');
var Promise = require('promise');
var fileUrl = require('file-url');
var reporter = require('./lib/reporter');
var chalk = require('chalk');
var request = require('then-request');
require('chromedriver');

//setup custom phantomJS capability
var phantomjs_exe = require('phantomjs-prebuilt').path;
var customPhantom = WebDriver.Capabilities.phantomjs().set('phantomjs.binary.path', phantomjs_exe);

module.exports = function (customOptions, done) {

	var defaultOptions = {
		folderOutputReport: 'aXeReports',
		browser: 'chrome',
		showOnlyViolations: false,
		verbose: false,
		saveOutputIn: '',
		tags: null,
		urls: [],
		threshold: 0
	};

	var options = customOptions ? Object.assign(defaultOptions, customOptions) : defaultOptions;
	var driver = options.browser === 'phantomjs' ? new WebDriver.Builder().withCapabilities(customPhantom).build() : new WebDriver.Builder().forBrowser(options.browser).build();
	var tagsAreDefined = (!Array.isArray(options.tags) && options.tags !== null && options.tags !== '') || (Array.isArray(options.tags) && options.tags.length > 0);

	var isRemoteUrl = function (url) {
		return url.indexOf('http://') >= 0 || url.indexOf('https://') >= 0;
	};

	var flatten = function (arr) {
		return [].concat.apply([], arr);
	};

	var getUrl = function (url) {
		return isRemoteUrl(url) ? url : fileUrl(url);
	}

	var checkNotValidUrls = function (result) {
		return new Promise(function (resolve) {
			request('GET', result.url, function (error, response) {
				result.status = (error) ? 404 : 200;
				resolve(result);
			});
		});
	}

	var getRemoteUrls = function (result) {
		if (isRemoteUrl(result.url)) {
			return result;
		}
	};

	var getLocalUrls = function (result) {
		if (!isRemoteUrl(result.url)) {
			return result;
		}
	};

	var onlyViolations = function(item) {
		return item.violations.length > 0;
	};

	var removePassesValues = function(item) {
		delete item.passes;
		return item;
	}

	var createResults = function (results) {
		var dest = '';
		var localUrls = results.filter(getLocalUrls);
		var remoteUrls = results.filter(getRemoteUrls);
		var promises = remoteUrls.map(checkNotValidUrls);
		Promise.all(promises).then(function (results) {
			results = localUrls.reduce(function (coll, item) {
				coll.push(item);
				return coll;
			}, results);
			if (options.showOnlyViolations) {
				results = results.map(removePassesValues).filter(onlyViolations);
			}
			if (options.saveOutputIn !== '') {
				dest = path.join(options.folderOutputReport, options.saveOutputIn);
				fs.writeFileSync(dest, JSON.stringify(results, null, '  '));
			}
			if (options.verbose) {
				console.log(chalk.yellow('Preparing results'));
				console.log(chalk.yellow('================='));
			}
			reporter(results, options.threshold);
			driver.quit().then(function () {
				done();
			});
		});

	};

	var findGlobPatterns = function (urls) {
		return urls.map(function (url) {
			return isRemoteUrl(url) ? url : glob.sync(url);
		});
	};

	var urls = flatten(findGlobPatterns(options.urls));

	var fileExists = function (filePath) {
		try {
			return fs.statSync(filePath).isFile();
		} catch (e) {
			return false;
		}
	}

	if (options.verbose) {
		console.log(chalk.yellow('Start reading the urls'));
		console.log(chalk.yellow('======================'));
	}
	Promise.all(urls.map(function (url) {
		return new Promise(function (resolve) {
			driver
				.get(getUrl(url))
				.then(function () {
					if (options.verbose) {
						console.log(chalk.cyan('Analysis start for: ') + url);
					}
					var startTimestamp = new Date().getTime();
					var axeBuilder = new AxeBuilder(driver);

					if (options.include) {
						axeBuilder.include(options.include);
					}

					if (options.exclude) {
						axeBuilder.exclude(options.exclude);
					}

					if (tagsAreDefined) {
						axeBuilder.withTags(options.tags);
					}

					if (options.a11yCheckOptions) {
						axeBuilder.options(options.a11yCheckOptions);
					}

					axeBuilder.analyze(function (results) {
						results.url = url;
						results.timestamp = new Date().getTime();
						results.time = results.timestamp - startTimestamp;
						if (options.verbose) {
							console.log(chalk.cyan('Analyisis finished for: ') + url);
						}
						resolve(results);
					});
				});
		});

	})).then(createResults);

};

@@ -1975,32 +1975,33 @@
 tions = function
+ 
 (item) %7B%0A%09%09retur
@@ -2069,16 +2069,17 @@
 function
+ 
 (item) %7B
@@ -2114,24 +2114,106 @@
 urn item;%0A%09%7D
+;%0A%0A%09var mergeArray = function (coll, item) %7B%0A%09%09coll.push(item);%0A%09%09return coll;%0A%09%7D;
 %0A%0A%09var creat
@@ -2411,16 +2411,42 @@
 dUrls);%0A
+%09%09var resultsForReporter;%0A
 %09%09Promis
@@ -2497,16 +2497,27 @@
 %09results
+ForReporter
  = local
@@ -2532,74 +2532,18 @@
 uce(
-function (coll, item) %7B%0A%09%09%09%09coll.push(item);%0A%09%09%09%09return coll;%0A%09%09%09%7D
+mergeArray
 , re
@@ -2598,26 +2598,48 @@
 %09results
- = results
+ForReporter = resultsForReporter
 .map(rem
@@ -2843,16 +2843,27 @@
 (results
+ForReporter
 , null, 
@@ -3029,16 +3029,27 @@
 (results
+ForReporter
 , option
@@ -3123,17 +3123,16 @@
 ;%0A%09%09%7D);%0A
-%0A
 %09%7D;%0A%0A%09va

create results for reporter