'use strict';

// If only node 6.X had utils.promisify().
const fs = require('fs');

/**
 * readdir(3) returned as a Promise
 *
 * @param {String} path The path we're looking at
 * @param {String or Object} options A config string/object
 * @return {Promise} Returns a promise that rejects if we couldn't
 *         read the directory, otherwise fulfills a list of Strings
 *         (the directory contents)
 */
const readdir = function(path, options) {
  return new Promise(function(resolve, reject) {
    fs.readdir(path, options, function(err, files) {
      if (err) {
        reject(err);
      } else {
        resolve(files);
      }
    });
  });
};

/**
 * stat(2) returned as a Promise
 *
 * @param {String} path The path we're looking at
 * @return {Promise} Returns a promise that rejects if we couldn't
 *         read the file/dir, otherwise fulfills with the file/dir's
 *         corresponding Stat object
 */
const stat = function(path) {
  return new Promise(function(resolve, reject) {
    fs.stat(path, function(err, stats) {
      if (err) {
        reject(err);
      } else {
        resolve(stats);
      }
    });
  });
};

// Read the contents of the current directory
readdir('.')
  .then(function(values) {
    // If we were able to read the contents of the directory,
    // create an Array of Promises to find the stats for each
    // of the directory's contents.
    let stat_promises = values.map(function(v) {
      return stat(v);
    });

    // Then turn that Array of Promises into a single Promise that
    // fulfills once **all** of the promises in the Array fulfill.
    // We need to return this guy, so that we can continue our
    // chain of Promises.
    return Promise.all(stat_promises);
  })
  .then(function(stats) {
    // If we were able to resolve our big Promise (the Promise.all),
    // then we can iterate through our array of Stat objects. Each
    // of the items in that original directory will have a Stat object
    // in the array.
    console.log(stats);
  })
  .catch(function(err) {
    // If there was an error at any point in our chain, we'll fall to
    // this catch case. Here, we'll just print out the error and be done.
    console.log(err);
  });