"use strict";

var _ = require('lodash');
var path = require('path');
var Schema = require('node-verifier-schema');
var iterate = require('async-iterate');

var defaultsOptions = {
	cwd: process.cwd(),

	getData: function (name) {
		return function (req, res) {
			return req[name];
		};
	},

	callback: function (err, req, res, next) {
		next(err);
	},

	preparePath: function (filepath) {
		return path.join(this.cwd, filepath);
	},

	prepareSchema: function (schema, options) {
		var _rawSchema = schema;
		if (_.isString(schema)) {
			if (/\.(yaml|yml)$/.test(schema)) {
				schema = options.preparePath(schema);
				schema = Schema.load(schema);
			} else {
				schema = Schema.get(schema);
			}
		} else if (_.isFunction(schema)) {
			schema = new Schema();
			_rawSchema.call(schema, schema.required.bind(schema), schema.optional.bind(schema));
		}

		if (!(schema instanceof Schema)) {
			throw new Error('must be Schema instance. ' + _rawSchema + ' given');
		}

		return schema;
	}
};

var expressVerifier = function (globalOptions) {
	var verifier = function (object, options) {
		if (_.isFunction(options)) {
			options = {
				callback: options
			};
		}

		options = _.extend({}, defaultsOptions, globalOptions, options);

		if (!_.isPlainObject(object)) {
			object = options.prepareSchema(object, options).fields;
		}

		var middleware = function (req, res, next) {
			iterate.each(middleware.verifiers, function (vierifier, _index, done) {
				vierifier.verify(req, res, function (err) {
					if (err instanceof Schema.ValidationError) {
						err.object = vierifier.name;
					}

					done(err);
				});
			}, function (err) {
				options.callback(err, req, res, next);
			});
		};

		middleware.verifiers = _.transform(verifier.components, function(verifiers, component, name) {
			if (!_.has(object, name)) {
				return;
			}

			verifiers.push({
				name: name,
				verify: component(object[name], options)
			});
		}, []);

		if (!middleware.verifiers.length) {
			throw new Error('invalid parameters for verify');
		}

		return middleware;
	};

	verifier.components = {};

	_.each(['params', 'headers', 'query', 'body'], function (name) {
		verifier.components[name] = function (schema, options) {
			var middleware = function (req, res, next) {
				middleware.verifier.verify(middleware.getData(req, res), next);
			};

			middleware.schema = options.prepareSchema(schema, options);
			middleware.verifier = middleware.schema.verifier(options);
			middleware.getData = options.getData(name);

			return middleware;
		};

		verifier[name] = function (object, options) {
			var obj = {};
			obj[name] = object;
			return verifier(obj, options);
		};
	});

	return verifier;
};

expressVerifier.Schema = Schema;
expressVerifier.Verifier = Schema.Verifier;

module.exports = expressVerifier;

@@ -1056,38 +1056,38 @@
 ier = function (
-object
+schems
 , options) %7B%0A%09%09i
@@ -1257,22 +1257,22 @@
 ect(
-object
+schems
 )) %7B%0A%09%09%09
 obje
@@ -1267,22 +1267,22 @@
 )) %7B%0A%09%09%09
-object
+schems
  = optio
@@ -1298,22 +1298,22 @@
 eSchema(
-object
+schems
 , option
@@ -1805,22 +1805,22 @@
 (!_.has(
-object
+schems
 , name))
@@ -1898,22 +1898,22 @@
 mponent(
-object
+schems
 %5Bname%5D, 

change var names