/*
	Licensed Material - Property of IBM

	(C) Copyright 2015, 2016 IBM Corp.

	Unless required by applicable law or agreed to in writing, software
	distributed under the License is distributed on an "AS IS" BASIS,
	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
	See the License for the specific language governing permissions and
	limitations under the License.
*/


'use strict';

var Q = require('q');
var fs = require('fs');
var path = require('path');

var externalizedStrings = require('./externalizedStrings');
var errors = require('mdo-errors');
var strings = require('ibm-strings');
var exec = require('mdo-exec').run;

var buildAdapter = function(directory) {
  var deferred = Q.defer();
  // Run mvn clean install
  exec('mvn', ['clean', 'install'], directory).then(function() {
    deferred.resolve({"directory": directory});
  }, function(err) {
    console.log('\n' + err.stdOut);
    //var errorBuild = errors.getError('ADAPTERBUILDERROR');
    //strings.fatal(errorBuild.description);
    deferred.reject({"err": err, "directory": directory});
  });
  return deferred.promise;
};

// Recursively search to find if there are nested adapters
var search = function(directory) {
  var pass = 0;
  var fail = 0;
  var promises = [];
  var deferred = Q.defer();
  fs.readdir(directory, function(err, directoryUnfiltered) {
    // Empty Folder
    if(directoryUnfiltered === undefined) {
      deferred.resolve({"pass": pass, "fail": fail});
    } else {
      // filter out all hidden directories/files that start with a '.'
      var directoryContent = [];
      directoryUnfiltered.forEach(function(item) {
        if(!item.startsWith('.')) {
          directoryContent.push(item);
        }
      });
      // Check if it's an adapter folder
      if(directoryContent.indexOf('pom.xml') !== -1) {
        // Adapter Folder
        fs.stat(path.join(directory, 'src', 'main', 'adapter-resources', 'adapter.xml'), function(err) {
          if(!err) {
            console.log(strings.format(externalizedStrings.buildingAdapterName, path.basename(directory)));
            buildAdapter(directory).then(function(resolve) {
              pass++;
              console.log(strings.format(externalizedStrings.successfulBuildName, path.basename(resolve.directory)));
              deferred.resolve({"pass": pass, "fail": fail});
            }).fail(function(err) {
              fail++;
              console.log(strings.format(externalizedStrings.errorBuildName, path.basename(err.directory)));
              deferred.resolve({"pass": pass, "fail": fail});
            });
          } else {
            // Otherwise continue looking for more adapters
            directoryContent.forEach(function(item) {
              var itemPath = path.join(directory, item);
              var check = fs.statSync(itemPath);
              if(check.isDirectory()) {
                promises.push(search(itemPath));
              }
              Q.all(promises).then(function(resolves) {
                resolves.forEach(function(resolve) {
                  pass += resolve.pass;
                  fail += resolve.fail;
                });
                deferred.resolve({"pass": pass, "fail": fail});
              });
            });
          }
        });
      } else {
        if(directoryContent.length === 0) {
          deferred.resolve({"pass": pass, "fail": fail});
        }
        directoryContent.forEach(function(item) {
          var itemPath = path.join(directory, item);
          var check = fs.statSync(itemPath);
          if(check.isDirectory()) {
            promises.push(search(itemPath));
          }
          Q.all(promises).then(function(resolves) {
            resolves.forEach(function(resolve) {
              pass += resolve.pass;
              fail += resolve.fail;
            });
            deferred.resolve({"pass": pass, "fail": fail});
          });
        });
      }
    }
  });
  return deferred.promise;
};

/**
 * actually do the work of the command
 */
module.exports.run = function(argv) {
  var deferred = Q.defer();
  
  // Command: 'mfpdev adapter build all'
  if (argv && argv[0] === 'all') {
    console.log(externalizedStrings.searchingAdapters);
    search(process.cwd()).then(function(response) {
      if(response.pass === 0 && response.fail === 0) {
        console.log(strings.format(externalizedStrings.noAdaptersFound));
        deferred.resolve();
      } else {
        console.log(strings.format(externalizedStrings.numberAdaptersBuilt, response.pass, response.fail));
        deferred.resolve();
      }
    }).fail(function(err) {
      console.log(err);
      deferred.reject(err.err);
    });
    
  // Command: 'mfpdev adapter build'
  } else {
    // Check for pom.xml
    if (!fs.existsSync('pom.xml') || !fs.existsSync(path.join('src', 'main', 'adapter-resources', 'adapter.xml'))) {
      var nonAdapterError = errors.getError('NONADAPTERFOLDER');
      strings.fatal(nonAdapterError.description);
      deferred.reject(nonAdapterError);
    }
    else {
      console.log(externalizedStrings.buildingAdapter);
      buildAdapter(process.cwd()).then(function() {
        console.log(strings.format(externalizedStrings.successfulBuild));
        deferred.resolve();
      }).fail(function(err) {
        console.log(externalizedStrings.errorBuild);
        console.log(err.stdOut);
        var errorBuild = errors.getError('ADAPTERBUILDERROR');
        strings.fatal(errorBuild.description);
        deferred.reject(errorBuild);
      });
    }
  }
  return deferred.promise;
};


// return the path to the md file (relative to basePath) for the specific command
module.exports.getHelpFilePath = function(basePath) {
  return path.join(basePath, 'mdo-adapter-actions', 'doc', 'build.txt');
};