/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/
"use strict";

const Resolver = require("./Resolver");

const SyncAsyncFileSystemDecorator = require("./SyncAsyncFileSystemDecorator");

const ParsePlugin = require("./ParsePlugin");
const DescriptionFilePlugin = require("./DescriptionFilePlugin");
const NextPlugin = require("./NextPlugin");
const TryNextPlugin = require("./TryNextPlugin");
const ModuleKindPlugin = require("./ModuleKindPlugin");
const FileKindPlugin = require("./FileKindPlugin");
const JoinRequestPlugin = require("./JoinRequestPlugin");
const ModulesInHierachicDirectoriesPlugin = require("./ModulesInHierachicDirectoriesPlugin");
const ModulesInRootPlugin = require("./ModulesInRootPlugin");
const AliasPlugin = require("./AliasPlugin");
const AliasFieldPlugin = require("./AliasFieldPlugin");
const ConcordExtensionsPlugin = require("./ConcordExtensionsPlugin");
const ConcordMainPlugin = require("./ConcordMainPlugin");
const ConcordModulesPlugin = require("./ConcordModulesPlugin");
const DirectoryExistsPlugin = require("./DirectoryExistsPlugin");
const FileExistsPlugin = require("./FileExistsPlugin");
const SymlinkPlugin = require("./SymlinkPlugin");
const MainFieldPlugin = require("./MainFieldPlugin");
const UseFilePlugin = require("./UseFilePlugin");
const AppendPlugin = require("./AppendPlugin");
const RootPlugin = require("./RootPlugin");
const RestrictionsPlugin = require("./RestrictionsPlugin");
const ResultPlugin = require("./ResultPlugin");
const ModuleAppendPlugin = require("./ModuleAppendPlugin");
const UnsafeCachePlugin = require("./UnsafeCachePlugin");

exports.createResolver = function(options) {
	//// OPTIONS ////

	// A list of directories to resolve modules from, can be absolute path or folder name
	let modules = options.modules || ["node_modules"];

	// A list of description files to read from
	const descriptionFiles = options.descriptionFiles || ["package.json"];

	// A list of additional resolve plugins which should be applied
	// The slice is there to create a copy, because otherwise pushing into plugins
	// changes the original options.plugins array, causing duplicate plugins
	const plugins = (options.plugins && options.plugins.slice()) || [];

	// A list of main fields in description files
	let mainFields = options.mainFields || ["main"];

	// A list of alias fields in description files
	const aliasFields = options.aliasFields || [];

	// A list of main files in directories
	const mainFiles = options.mainFiles || ["index"];

	// A list of extensions which should be tried for files
	let extensions = options.extensions || [".js", ".json", ".node"];

	// Enforce that a extension from extensions must be used
	const enforceExtension = options.enforceExtension || false;

	// A list of module extensions which should be tried for modules
	let moduleExtensions = options.moduleExtensions || [];

	// Enforce that a extension from moduleExtensions must be used
	const enforceModuleExtension = options.enforceModuleExtension || false;

	// A list of module alias configurations or an object which maps key to value
	let alias = options.alias || [];

	// Resolve symlinks to their symlinked location
	const symlinks =
		typeof options.symlinks !== "undefined" ? options.symlinks : true;

	// Resolve to a context instead of a file
	const resolveToContext = options.resolveToContext || false;

	// A list of root paths
	const roots = options.roots || [];

	// Ignore errors happening when resolving roots
	const ignoreRootsErrors = options.ignoreRootsErrors || false;

	// Prefer to resolve server-relative urls as absolute paths before falling back to resolve in roots
	const preferAbsolute = options.preferAbsolute || false;

	const restrictions = options.restrictions || [];

	// Use this cache object to unsafely cache the successful requests
	let unsafeCache = options.unsafeCache || false;

	// Whether or not the unsafeCache should include request context as part of the cache key.
	const cacheWithContext =
		typeof options.cacheWithContext !== "undefined"
			? options.cacheWithContext
			: true;

	// Enable concord description file instructions
	const enableConcord = options.concord || false;

	// A function which decides whether a request should be cached or not.
	// an object is passed with `path` and `request` properties.
	const cachePredicate =
		options.cachePredicate ||
		function() {
			return true;
		};

	// The file system which should be used
	const fileSystem = options.fileSystem;

	// Use only the sync constiants of the file system calls
	const useSyncFileSystemCalls = options.useSyncFileSystemCalls;

	// A prepared Resolver to which the plugins are attached
	let resolver = options.resolver;

	//// options processing ////

	if (!resolver) {
		resolver = new Resolver(
			useSyncFileSystemCalls
				? new SyncAsyncFileSystemDecorator(fileSystem)
				: fileSystem
		);
	}

	extensions = [].concat(extensions);
	moduleExtensions = [].concat(moduleExtensions);

	modules = mergeFilteredToArray([].concat(modules), item => {
		return !isAbsolutePath(item);
	});

	mainFields = mainFields.map(item => {
		if (typeof item === "string" || Array.isArray(item)) {
			item = {
				name: item,
				forceRelative: true
			};
		}
		return item;
	});

	if (typeof alias === "object" && !Array.isArray(alias)) {
		alias = Object.keys(alias).map(key => {
			let onlyModule = false;
			let obj = alias[key];
			if (/\$$/.test(key)) {
				onlyModule = true;
				key = key.substr(0, key.length - 1);
			}
			if (typeof obj === "string") {
				obj = {
					alias: obj
				};
			}
			obj = Object.assign(
				{
					name: key,
					onlyModule: onlyModule
				},
				obj
			);
			return obj;
		});
	}

	if (unsafeCache && typeof unsafeCache !== "object") {
		unsafeCache = {};
	}

	//// pipeline ////

	resolver.ensureHook("resolve");
	resolver.ensureHook("parsedResolve");
	resolver.ensureHook("describedResolve");
	resolver.ensureHook("rawModule");
	resolver.ensureHook("module");
	resolver.ensureHook("relative");
	resolver.ensureHook("describedRelative");
	resolver.ensureHook("directory");
	resolver.ensureHook("existingDirectory");
	resolver.ensureHook("undescribedRawFile");
	resolver.ensureHook("rawFile");
	resolver.ensureHook("file");
	resolver.ensureHook("existingFile");
	resolver.ensureHook("resolved");

	// resolve
	if (unsafeCache) {
		plugins.push(
			new UnsafeCachePlugin(
				"resolve",
				cachePredicate,
				unsafeCache,
				cacheWithContext,
				"new-resolve"
			)
		);
		plugins.push(new ParsePlugin("new-resolve", "parsed-resolve"));
	} else {
		plugins.push(new ParsePlugin("resolve", "parsed-resolve"));
	}

	// parsed-resolve
	plugins.push(
		new DescriptionFilePlugin(
			"parsed-resolve",
			descriptionFiles,
			"described-resolve"
		)
	);
	plugins.push(new NextPlugin("after-parsed-resolve", "described-resolve"));

	// described-resolve
	if (alias.length > 0)
		plugins.push(new AliasPlugin("described-resolve", alias, "resolve"));
	if (enableConcord) {
		plugins.push(new ConcordModulesPlugin("described-resolve", {}, "resolve"));
	}
	aliasFields.forEach(item => {
		plugins.push(new AliasFieldPlugin("described-resolve", item, "resolve"));
	});
	plugins.push(new ModuleKindPlugin("after-described-resolve", "raw-module"));
	if (preferAbsolute) {
		plugins.push(new JoinRequestPlugin("after-described-resolve", "relative"));
	}
	roots.forEach(root => {
		plugins.push(
			new RootPlugin(
				"after-described-resolve",
				root,
				"relative",
				ignoreRootsErrors
			)
		);
	});
	if (!preferAbsolute) {
		plugins.push(new JoinRequestPlugin("after-described-resolve", "relative"));
	}

	// raw-module
	moduleExtensions.forEach(item => {
		plugins.push(new ModuleAppendPlugin("raw-module", item, "module"));
	});
	if (!enforceModuleExtension)
		plugins.push(new TryNextPlugin("raw-module", null, "module"));

	// module
	modules.forEach(item => {
		if (Array.isArray(item))
			plugins.push(
				new ModulesInHierachicDirectoriesPlugin("module", item, "resolve")
			);
		else plugins.push(new ModulesInRootPlugin("module", item, "resolve"));
	});

	// relative
	plugins.push(
		new DescriptionFilePlugin(
			"relative",
			descriptionFiles,
			"described-relative"
		)
	);
	plugins.push(new NextPlugin("after-relative", "described-relative"));

	// described-relative
	plugins.push(new FileKindPlugin("described-relative", "raw-file"));
	plugins.push(
		new TryNextPlugin("described-relative", "as directory", "directory")
	);

	// directory
	plugins.push(new DirectoryExistsPlugin("directory", "existing-directory"));

	if (resolveToContext) {
		// existing-directory
		plugins.push(new NextPlugin("existing-directory", "resolved"));
	} else {
		// existing-directory
		if (enableConcord) {
			plugins.push(new ConcordMainPlugin("existing-directory", {}, "resolve"));
		}
		mainFields.forEach(item => {
			plugins.push(new MainFieldPlugin("existing-directory", item, "resolve"));
		});
		mainFiles.forEach(item => {
			plugins.push(
				new UseFilePlugin("existing-directory", item, "undescribed-raw-file")
			);
		});

		// undescribed-raw-file
		plugins.push(
			new DescriptionFilePlugin(
				"undescribed-raw-file",
				descriptionFiles,
				"raw-file"
			)
		);
		plugins.push(new NextPlugin("after-undescribed-raw-file", "raw-file"));

		// raw-file
		if (!enforceExtension) {
			plugins.push(new TryNextPlugin("raw-file", "no extension", "file"));
		}
		if (enableConcord) {
			plugins.push(new ConcordExtensionsPlugin("raw-file", {}, "file"));
		}
		extensions.forEach(item => {
			plugins.push(new AppendPlugin("raw-file", item, "file"));
		});

		// file
		if (alias.length > 0)
			plugins.push(new AliasPlugin("file", alias, "resolve"));
		if (enableConcord) {
			plugins.push(new ConcordModulesPlugin("file", {}, "resolve"));
		}
		aliasFields.forEach(item => {
			plugins.push(new AliasFieldPlugin("file", item, "resolve"));
		});
		if (symlinks) plugins.push(new SymlinkPlugin("file", "relative"));
		plugins.push(new FileExistsPlugin("file", "existing-file"));

		// existing-file
		plugins.push(new NextPlugin("existing-file", "resolved"));
	}

	// resolved
	if (restrictions.length > 0) {
		plugins.push(new RestrictionsPlugin(resolver.hooks.resolved, restrictions));
	}
	plugins.push(new ResultPlugin(resolver.hooks.resolved));

	//// RESOLVER ////

	plugins.forEach(plugin => {
		plugin.apply(resolver);
	});

	return resolver;
};

function mergeFilteredToArray(array, filter) {
	return array.reduce((array, item) => {
		if (filter(item)) {
			const lastElement = array[array.length - 1];
			if (Array.isArray(lastElement)) {
				lastElement.push(item);
			} else {
				array.push([item]);
			}
			return array;
		} else {
			array.push(item);
			return array;
		}
	}, []);
}

function isAbsolutePath(path) {
	return /^[A-Z]:|^\//.test(path);
}
