/*
 * grunt-manifest-concat
 * https://github.com/mcavallo
 *
 * Copyright (c) 2015 Mariano Cavallo
 * Licensed under the MIT license.
 */

'use strict';

var fs = require('fs'),
    path = require('path'),
    chalk = require('chalk');

module.exports = function(grunt) {

  var options,
      baseCwd = process.cwd(),
      manifestFile = require('./lib/manifestFile').init(grunt);

  // Solves dependencies not loading if the base was changed on runtime
  var fromBaseCwd = function(callback) {
    var cwd = process.cwd();
    process.chdir(baseCwd);
    callback.call(this);
    process.chdir(cwd);
  }

  grunt.registerMultiTask('manifest', 'Turn manifest files into concatenated files.', function () {

    var concat = grunt.config.get('concat') || {},
        tasks = [];

    fromBaseCwd(function() {
      // Load dependent tasks
      grunt.loadNpmTasks('grunt-contrib-concat');
    });

    options = this.options({
      sourceMap: false,
      banner: false,
      extension: 'js',
      cwd: ''
    });

    this.files.forEach(function(f) {
      f.orig.src.forEach(function(src) {
        // Only proceed if the src is a directory
        if (!grunt.file.isDir(src))
          return grunt.log.writeln(chalk.yellow('SKIPPED ') + ' Specified source is not a directory.');

        // If dest is set, It should be a directory
        if (!grunt.file.isDir(f.orig.dest))
          return grunt.log.writeln(chalk.yellow('SKIPPED ') + ' Specified destination is not a directory.');

        // Scan the directory for manifest files
        grunt.file.expand(path.join(src, '*.json')).forEach(function(manifestPath) {
          var manifest = manifestFile.new({
            filePath: manifestPath,
            dest: f.orig.dest,
            options: options
          });

          // Skip manifest if It's invalid
          if (!manifest.isValid())
            return;

          // Create the concat subtask for each manifest file
          concat[manifest.taskName()] = manifest.taskSettings();
          tasks.push(manifest.taskName());
        });
      });
    });

    // Only proceed if any tasks were added
    if (!tasks.length)
      return;

    // Add module subtasks to the concat task in initConfig
    grunt.config.set('concat', concat);

    // Run all the defined tasks
    for (var i = 0, t = tasks.length; i < t; i++)
      grunt.task.run('concat:' + tasks[i]);
  });
};

@@ -602,16 +602,827 @@
 );%0A  %7D%0A%0A
+  var eachSourceDir = function(callback) %7B%0A    this.files.forEach(function(f) %7B%0A      f.orig.src.forEach(function(src) %7B%0A        // Only proceed if the src is a directory%0A        if (grunt.file.isDir(src))%0A          callback.call(this, src, f.orig.dest);%0A        else%0A          printWarning('Specified source is not a directory.');%0A      %7D);%0A    %7D);%0A  %7D%0A%0A  var eachManifest = function(src, dest, options, callback) %7B%0A    grunt.file.expand(path.join(src, '*.json')).forEach(function(manifestPath) %7B%0A      var manifest = manifestFile.new(%7B%0A        filePath: manifestPath,%0A        dest: dest,%0A        options: options%0A      %7D);%0A%0A      if (manifest.isValid())%0A        callback.call(this, manifest);%0A    %7D);%0A  %7D%0A%0A  var printWarning = function(msg) %7B%0A    grunt.log.writeln(chalk.yellow('SKIPPED ') + ' ' + msg);%0A  %7D%0A%0A
   grunt.
@@ -1513,17 +1513,16 @@
 on () %7B%0A
-%0A
     var 
@@ -1831,275 +1831,44 @@
     
-this.files.forEach(function(f) %7B%0A      f.orig.src.forEach(function(src) %7B%0A        // Only proceed if the src is a directory%0A        if (!grunt.file.isDir(src))%0A          return grunt.log.writeln(chalk.yellow('SKIPPED ') + ' Specified source is not a directory.');%0A%0A  
+eachSourceDir(function(src, dest) %7B%0A
     
@@ -1919,22 +1919,28 @@
 y%0A      
-  
 if (
+dest && 
 !grunt.f
@@ -1953,24 +1953,15 @@
 Dir(
-f.orig.
 dest))%0A
-  
     
@@ -1975,55 +1975,22 @@
 urn 
-grunt.log.writeln(chalk.yellow('SKIPPED ') + ' 
+printWarning('
 Spec
@@ -2041,454 +2041,120 @@
     
-  
 // 
-Scan the directory for manifest files%0A        grunt.file.expand(path.join(src, '*.json')).forEach(function(manifestPath) %7B%0A          var manifest = manifestFile.new(%7B%0A            filePath: manifestPath,%0A            dest: f.orig.dest,%0A            options: options%0A          %7D);%0A%0A          // Skip manifest if It's invalid%0A          if (!manifest.isValid())%0A            return;%0A%0A          // Create the concat subtask for each manifest file%0A  
+Create the concat subtask for each manifest file%0A      eachManifest(src, dest, options, function(manifest) %7B%0A
     
@@ -2216,26 +2216,24 @@
 ();%0A        
-  
 tasks.push(m
@@ -2257,20 +2257,8 @@
 ));%0A
-        %7D);%0A
     

Split manifest task in smaller methods.