
###
Walker
###

Q     = require('q')
_     = require('lodash')
fs    = require('fs')
path  = require('path')

module.exports = (cwd, callback) ->

  # Main promise
  mainDeferred = Q.defer()


  # File walker
  _walker = (cwd) ->
    promises = []
    deferred = Q.defer()

    fs.readdir cwd, (err, files) ->
      deferred.reject(new Error(err)) if err

      promises = _.map files, (file) ->
        filePath = path.join(cwd, file)
        _executor(file, filePath)

      Q.allSettled(promises).then(_resolver deferred)

    deferred.promise


  # File execution
  _executor = (file, filePath) ->
    deferred = Q.defer()

    fs.stat filePath, (err, stats) ->
      deferred.reject(new Error(err)) if err

      if stats.isDirectory()
        _walker(filePath).then(_resolver deferred)
      else if stats.isFile()
        callback(filePath).then(_resolver deferred)

    deferred.promise


  # Promise resolver
  _resolver = (deferred) ->
    (promise) -> deferred.resolve(promise)


  # Start
  _walker(cwd).then (promises) ->
    mainDeferred.resolve(_.flatten promises)


  # Return main promise
  mainDeferred.promise
