(function() {
  'use strict';

  require('colors');
  var fs = require('fs'),
    assert = require('assert'),
    log = require('npmlog'),
    yaml = require('js-yaml');

  module.exports = {
    log: log,

    error: {
      warning: 'Policy not set, All traffic will be denied'.yellow,
      err: {
        required: 'group, permissions, resources,'.red
      }
    },

    /**
     * [validate checks for the validity of the config file]

     * @param  {[JSON]} config [contains the rules from the json file]
     * @return {[JSON]}
     */
    validate: function(config) {
      var self = this;
      var permissions;

      /**
       * Check if config is a array
       */
      if (!Array.isArray(config)) {

        /* istanbul ignore next */
        throw new Error('Config json file should be an Array of rules');

      } else if (config.length === 0) {
        return self.error.warning;
      }

      /**
       * Ensure that the config file has the core properties
       */
      config.forEach(function(el) {
        if (el.group && el.permissions) {
          /**
           * Assert that they are of the correct type
           */
          assert.deepEqual(typeof el.group, 'string');
          assert(Array.isArray(el.permissions), true);

          permissions = el.permissions;
          permissions.forEach(function(policy) {
            assert(policy.resource, true);
            assert(policy.methods, true);
            assert(policy.action, true);
          });

          return;
        }

        /* istanbul ignore next */
        return log.error('REQUIRED:', self.error.err.required);
      });

      return config;
    },

    readJson: function(path, encoding, yml) {
      var config, buffer;
      /**
       * Read the config file with the rules.
       *
       */
      try {
        buffer = fs.readFileSync(path, { encoding: encoding });

        if (yml) {
          config = yaml.safeLoad(buffer);
        } else {
          config = JSON.parse(buffer);
        }
      } catch (e) {
        /* istanbul ignore next */
        throw Error(e);
      }

      return this.validate(config);
    },

    /**
     * [group Gets the group from the array
     * of rules based on the role of the user]
     * @param  {[Array]} rule
     * @param  {[String]} role
     * @return {[Object]}
     */
    group: function(res, rules, role) {
      var group = rules.find(function(el) {
        return el.group === role;
      });

      if (group) {
        return group;
      } else {
        return res
          .status(403)
          .send({
            status: 403,
            success: false,
            error: 'ACCESS DENIED'
          });
      }
    },

    /**
     * [methods Gets the methods from the selected group]
     * @param  {[Object]} group
     * @param  {[String]} resource
     * @return {[Array/String]} Returns an array of methods
     * or a string incase a glob is used;
     */
    policy: function(group, resource) {
      var permissions = group.permissions.find(function(el) {
        return el.resource === resource;
      });
      return (permissions) ? {
        methods: permissions.methods,
        action: permissions.action
      } : permissions;
    },

    role: function(res, decoded, session) {
      if (decoded && decoded.role) {
        return decoded.role;
      } else if (session && session.role) {
        return session.role;
      } else {
        log.warn('MISSING', 'Role not defined,' +
          ' All traffic will be blocked'.yellow);
        return res
          .status(403)
          .send({
            status: 403,
            success: false,
            error: 'ACCESS DENIED'
          });
      }
    },

    resource: function(next, url, baseUrl) {
      var lengthOfTheBaseUrl = 0,
        base;
      // Get the base url in an array
      if (baseUrl) {
        base = baseUrl.match(/([A-Z])\w+/gi);
      }

      // Get the url in an array
      var arr = url.match(/([A-Z])\w+/gi);

      if (!arr) {
        return next();
      } else {
        // if we have the base get its length
        if (base) {
          lengthOfTheBaseUrl = base.length;
        }
        // Remove the base url from the originalUrl if it exist
        arr = arr.splice(lengthOfTheBaseUrl);
        return arr[0];
      }
    }
  };
})();

@@ -164,16 +164,621 @@
 aml');%0A%0A
+  /**%0A   * Ensure that the config file has the core properties%0A  */%0A  var checkProperties = function(error, config) %7B%0A    var permissions;%0A%0A    config.forEach(function(el) %7B%0A      if ((typeof el.group === 'string') && (Array.isArray(el.permissions))) %7B%0A        permissions = el.permissions;%0A%0A        permissions.forEach(function(policy) %7B%0A          assert(policy.resource, true);%0A          assert(policy.methods, true);%0A          assert(policy.action, true);%0A        %7D);%0A        return;%0A      %7D%0A      /* istanbul ignore next */%0A      return log.error('REQUIRED:', error);%0A    %7D);%0A    return config;%0A  %7D;%0A%0A
   module
@@ -790,16 +790,16 @@
 rts = %7B%0A
-
     log:
@@ -890,23 +890,8 @@
 ow,%0A
-      err: %7B%0A  
     
@@ -939,24 +939,16 @@
 s,'.red%0A
-      %7D%0A
     %7D,%0A%0A
@@ -1016,17 +1016,16 @@
 g file%5D%0A
-%0A
      * @
@@ -1111,24 +1111,23 @@
 %5BJSON%5D%7D%0A
- 
     */%0A
+
     vali
@@ -1155,111 +1155,8 @@
 ) %7B%0A
-      var self = this;%0A      var permissions;%0A%0A      /**%0A       * Check if config is a array%0A       */%0A
     
@@ -1187,17 +1187,16 @@
 fig)) %7B%0A
-%0A
         
@@ -1295,17 +1295,16 @@
 ules');%0A
-%0A
       %7D 
@@ -1350,20 +1350,20 @@
  return 
-self
+this
 .error.w
@@ -1381,751 +1381,84 @@
    %7D
-%0A%0A      /**%0A       * Ensure that the config file has the core properties%0A       */%0A      config.forEach(function(el) %7B%0A        if (el.group && el.permissions) %7B%0A          /**%0A           * Assert that they are of the correct type%0A           */%0A          assert.deepEqual(typeof el.group, 'string');%0A          assert(Array.isArray(el.permissions), true);%0A%0A          permissions = el.permissions;%0A          permissions.forEach(function(policy) %7B%0A            assert(policy.resource, true);%0A            assert(policy.methods, true);%0A            assert(policy.action, true);%0A          %7D);%0A%0A          return;%0A        %7D%0A%0A        /* istanbul ignore next */%0A        return log.error('REQUIRED:', self.error.err.required);%0A      %7D);%0A%0A      return config;
+ else %7B%0A        return checkProperties(this.error.required, config);%0A      %7D
 %0A   

Refactor validate function