'use strict';

const _ = require('lodash');
const { isSemver } = require('./utils');
const Formatter = require('./formatters/text');
const path = require('path');

const debug = require('debug')('gint:runner');

const run = (name, rule, opts) => {
  debug('Exec rule "%s"', name);
  const checker = require(path.join(__dirname, 'rules', name));
  if (checker.hookName !== opts.hookName || isSemver(opts)) {
    return Promise.resolve();
  }
  return checker.check(rule, opts);
};


module.exports = (config, opts) => new Promise((resolve, reject) => {
  debug('Starting');

  let errored = false;
  const formatter = new Formatter();
  const rules = _.map(config.rules, (rule, name) => ({ name, rule }));

  const end = () => {
    const output = formatter.result();
    debug('Finishing', { errored, output });
    errored ? reject(output) : resolve(output);
  };

  const iterate = (i) => {
    if (i >= rules.length) {
      end();
      return;
    }

    const { rule, name } = rules[i];

    run(name, rule, opts)
      .then(() => iterate(i + 1))
      .catch((err) => {
        const level = rule[0];
        if (level === 'err' || level === 'error') {
          errored = true;
          formatter.line('error', name, err);
        } else if (level === 'warn' || level === 'warning') {
          formatter.line('warning', name, err);
        }
        iterate(i + 1);
      });
  };

  iterate(0);
});

@@ -705,356 +705,98 @@
 %0A%0A  
-const end = () =%3E %7B%0A    const output = formatter.result();%0A    debug('Finishing', %7B errored, output %7D);%0A    errored ? reject(output) : resolve(output);%0A  %7D;%0A%0A  const iterate = (i) =%3E %7B%0A    if (i %3E= rules.length) %7B%0A  
+_.reduce(rules, (result, %7B rule, name %7D) =%3E result%0A
     
+.th
 en
-d();%0A      return;%0A    %7D%0A%0A    const %7B rule, name %7D = rules%5Bi%5D;%0A%0A    run(name, rule, opts)%0A      .then(() =%3E iterate(i + 1))%0A  
+(() =%3E run(name, rule, opts))%0A
     
@@ -819,18 +819,16 @@
 %7B%0A      
-  
 const le
@@ -842,18 +842,16 @@
 ule%5B0%5D;%0A
-  
       if
@@ -900,18 +900,16 @@
         
-  
 errored 
@@ -916,18 +916,16 @@
 = true;%0A
-  
         
@@ -966,18 +966,16 @@
 ;%0A      
-  
 %7D else i
@@ -1024,26 +1024,24 @@
 ) %7B%0A        
-  
 formatter.li
@@ -1076,63 +1076,198 @@
     
-  %7D%0A        iterate(i + 1);%0A      %7D);%0A  %7D;%0A%0A  iterate(0
+%7D%0A    %7D), Promise.resolve())%0A    .then(() =%3E %7B%0A      const output = formatter.result();%0A      debug('Finishing', %7B errored, output %7D);%0A      errored ? reject(output) : resolve(output);%0A    %7D
 );%0A%7D

Refactor iteratee with _.reduce