const R = require('ramda');
const templates = require('./templates');

/**
 * Helpers
 */

const isError = (code) => code && code[0] === 'E';
const createWriter =  R.curry(
  (testing, msg) => testing ? msg : process.stdout.write(msg)
);

const calculateFailures = function (results) {
  const codes = results.map((x) => x.error.code);
  return {
    failures: results.length,
    errors: codes.filter(isError).length,
    warnings: codes.filter(R.complement(isError)).length
  };
};

/**
 * Content Helpers
 */

function prepareContent(results) {
  if (results.length === 0) { return templates.noItems; }
  return results.reduce((obj, element) => {
    if (obj.previous !== element.file) {
      obj.previous = element.file;
      obj.content += templates.itemHeader.replace('{file}', element.file);
    }
    obj.content += templates.item
      .replace('{class}', isError(element.error.code) ? 'danger' : 'warning')
      .replace('{code}', element.error.code)
      .replace('{line}', element.error.line)
      .replace('{character}', element.error.character)
      .replace('{evidence}', element.error.evidence)
      .replace('{reason}', element.error.reason);
    return obj;
  }, { previous: null, content: '' });
}

function prepareSummary(failureCounts) {
  if (failureCounts.failures === 0) { return ''; }
  return templates.summary
    .replace('{failures}', failureCounts.failures)
    .replace('{errors}', failureCounts.errors)
    .replace('{warnings}', failureCounts.warnings);
}

/**
 * Exports
 */

module.exports = {
  reporter: function (results, testing) {
    const writer = createWriter(testing);
    const failureCounts = calculateFailures(results);
    const output = templates.body
      .replace('{content}', prepareContent(results))
      .replace('{summary}', prepareSummary(failureCounts));

    writer(output);
  }
};

@@ -84,16 +84,87 @@
 rs%0A */%0A%0A
+const isArray = R.allPass(%5BR.isArrayLike, R.pipe(R.length, R.gt(0))%5D);%0A
 const is
@@ -616,66 +616,8 @@
 ) %7B%0A
-  if (results.length === 0) %7B return templates.noItems; %7D%0A
   re
@@ -1276,59 +1276,8 @@
 ) %7B%0A
-  if (failureCounts.failures === 0) %7B return ''; %7D%0A
   re
@@ -1575,16 +1575,69 @@
 sting);%0A
+    const errors = isArray(results) ? results : %5B%5D;%0A%0A
     cons
@@ -1672,22 +1672,21 @@
 ailures(
-result
+error
 s);%0A    
@@ -1699,16 +1699,54 @@
 output =
+ results && results.length %3E 0%0A      ?
  templat
@@ -1753,16 +1753,18 @@
 es.body%0A
+  
       .r
@@ -1802,18 +1802,19 @@
 ent(
-result
+error
 s))%0A
+  
     
@@ -1867,22 +1867,55 @@
 Counts))
-;%0A
 %0A   
+   : templates.noItems;%0A%0A    return
  writer(

Fix some issues with the reporter