import {parseAsync} from 'json2csv';

export default function csv(input: any[], f: (err, data) => void) {
  parseAsync(input.map(e => flatten(e)), {includeEmptyRows: true})
    .then(csv => f(null, csv))
    .catch(err => f(err, null));
}

function flatten (data) {  // flatten object: {a: {b: true}} -> {a.b: true}
  const result = {};
  function recurse (cur, prop) {
    if (Object(cur) !== cur || Object.keys(cur).length === 0) {
      result[prop] = cur;
    }
    else if (Array.isArray(cur)) {
      if (cur.length && (Object(cur[0]) !== cur || Object.keys(cur[0]).length === 0)) {  // array of non-objects
        result[prop] = '[' + cur.join(', ') + ']';
      }
      else {
        let l = 0;
        for(let i = 0, l = cur.length; i < l; i++)
          recurse(cur[i], prop + "[" + i + "]");
        if (l == 0)
          result[prop] = [];
      }
    }
    else {
      let isEmpty = true;
      for (let p in cur) {
        isEmpty = false;
        recurse(cur[p], prop ? prop+"."+p : p);
      }
      if (isEmpty && prop)
        result[prop] = {};
    }
  }
  recurse(data, '');
  return result;
}