import { without } from 'lodash'

import {
  DEPENDENCIES_KEY
} from './configKeys'

// Constants
const NEVER_RUN = Symbol('NEVER_RUN')
const RUNNING = Symbol('RUNNING')
const DONE = Symbol('DONE')

import { startCommand, logError } from './log'

export default async function runTasks (sortedTaskArray) {
  // First tag every task with a status of NEVER_RUN
  const taggedTasks = sortedTaskArray.map((task) => ({ ...task, status: NEVER_RUN }))

  // Then down the rabbit hole we go!
  return recurse(taggedTasks)
}

function recurse (tasks) {
  // We are going to map over every task, and handle each one
  return Promise.all(tasks.map(async function (task) {
    if (task[DEPENDENCIES_KEY].length > 0 || task.status !== NEVER_RUN) {
      return Promise.resolve()
    }
    // If the task has no dependencies and has never been run, then run it
    if (task[DEPENDENCIES_KEY].length === 0 && task.status === NEVER_RUN) {
      // Set it to running, then await the command to finish
      task.status = RUNNING

      await handleCommand(task)

      // When it's done, mark it as done then remove it from all other tasks' dependencies
      task.status = DONE
      for (let innerTask of tasks) {
        innerTask[DEPENDENCIES_KEY] = without(innerTask[DEPENDENCIES_KEY], task.name)
      }

      // Finally, re-run the recursive function and return it's result
      return recurse(tasks)
    }
  }))
}

async function handleCommand (task) {

}

@@ -13,34 +13,100 @@
 hout
- %7D from 'lodash'%0A%0Aimport %7B
+, isArray, isFunction, isString, isEmpty %7D from 'lodash'%0A%0Aimport %7B%0A  COMMAND_KEY,%0A  ENV_KEY,
 %0A  D
@@ -258,16 +258,58 @@
 DONE')%0A%0A
+import %7B runCommand %7D from './runCommand'%0A
 import %7B
@@ -1132,23 +1132,20 @@
 t handle
-Command
+Task
 (task)%0A%0A
@@ -1531,24 +1531,553 @@
 ndle
-Command (task) %7B%0A
+Task (%7B %5BCOMMAND_KEY%5D: commands, %5BENV_KEY%5D: env %7D) %7B%0A  const name = 'NOT DONE!!!'%0A  // Ensure commands is an array%0A  const commandsArray = (isArray(commands) ? commands : %5Bcommands%5D)%0A%0A  for (let command of commandsArray) %7B%0A    // If it's a function, invoke it and use the result as the command to execute%0A    if (isFunction(command)) %7B%0A      command = await command()%0A    %7D%0A%0A    if (isString(command) && !isEmpty(command)) %7B%0A      await runCommand(command)%0A    %7D else %7B%0A      logError(%60Command for task %22$%7Bname%7D%22 is not a valid string%60)%0A    %7D%0A  %7D
 %0A%7D%0A

add handleTask