var async = require('async');
var _ = require('lodash');
var DockerRunner = require('../src/RunWrappers/Docker');
var RunListHelper = require('../src/RunListHelper');
var green = '\u001b[42m \u001b[0m';
var red = '\u001b[41m \u001b[0m';

module.exports = {
  name: 'pull-docker',
  description: 'Pulls latest docker images',
  usage: '[-r <repoPattern>]',
  options: [{
    name: 'noremote',
    alias: 'nr',
    type: 'boolean',
    desc: 'Do not pull docker images for remote repositories (dependencies)',
  }],
};

function dockerPullService(bosco, definition, next) {
  if (definition.service && definition.service.type === 'docker') {
    DockerRunner.update(definition, function(err) {
      if (err) {
        var errMessage = err.reason ? err.reason : err;
        bosco.error('Error pulling ' + definition.name + ', reason: ' + errMessage);
      }
      next();
    });
  } else {
    return next();
  }
}

function dockerPullRemote(bosco, repos, runConfig, next) {
  var isLocalService = !!(runConfig.service && runConfig.service.type);
  var isLocalRepo = _.includes(repos, runConfig.name);
  if (isLocalService || isLocalRepo) {
    return next();
  }
  RunListHelper.getServiceConfigFromGithub(bosco, runConfig.name, function(err, svcConfig) {
    if (err) {
      return next();
    }
    if (!svcConfig.name) {
      svcConfig.name = runConfig.name;
    }
    dockerPullService(bosco, svcConfig, next);
  });
}

function dockerPull(bosco, progressbar, bar, repoPath, repo, next) {
  var boscoService = [repoPath, 'bosco-service.json'].join('/');
  if (bosco.exists(boscoService)) {
    var definition = require(boscoService);
    dockerPullService(bosco, definition, next);
  } else {
    return next();
  }
}

function cmd(bosco, args, next) {
  var repoPattern = bosco.options.repo;
  var repoRegex = new RegExp(repoPattern);
  var watchNothing = '$a';
  var noRemote = bosco.options.noremote;

  var repos = bosco.getRepos();
  if (!repos) return bosco.error('You are repo-less :( You need to initialise bosco first, try \'bosco clone\'.');

  function pullDockerImages(cb) {
    bosco.log('Checking for local docker images to pull ...');

    var progressbar = bosco.config.get('progress') === 'bar';
    var total = repos.length;

    var bar = progressbar ? new bosco.Progress('Doing docker pull [:bar] :percent :etas', {
      complete: green,
      incomplete: red,
      width: 50,
      total: total,
    }) : null;

    // Get the dependencies
    async.mapSeries(repos, function doDockerPull(repo, repoCb) {
      if (!repo.match(repoRegex)) return repoCb();
      var repoPath = bosco.getRepoPath(repo);
      dockerPull(bosco, progressbar, bar, repoPath, repo, repoCb);
    }, function() {
      cb();
    });
  }

  function pullDependentDockerImages(cb) {
    if (noRemote) {
      bosco.log('Skipping check and pull of remote images ...'.cyan);
      return cb();
    }
    bosco.log('Checking for remote docker images to pull ...');
    RunListHelper.getRunList(bosco, repos, repoRegex, watchNothing, null, function(err, services) {
      if (err) {
        return next(err);
      }
      async.mapSeries(services, function doDockerPullRemote(runConfig, pullCb) {
        dockerPullRemote(bosco, repos, runConfig, pullCb);
      }, cb);
    });
  }

  function initialiseRunners(cb) {
    DockerRunner.init(bosco, cb);
  }

  function disconnectRunners(cb) {
    DockerRunner.disconnect(cb);
  }

  async.series([
    initialiseRunners,
    pullDockerImages,
    pullDependentDockerImages,
    disconnectRunners,
  ], function() {
    bosco.log('Complete!');
    if (next) next();
  });
}

module.exports.cmd = cmd;

@@ -571,16 +571,17 @@
 %7B%0A  if (
+!
 definiti
@@ -591,18 +591,18 @@
 service 
-&&
+%7C%7C
  definit
@@ -618,19 +618,19 @@
 ce.type 
+!
 ==
-=
  'docker
@@ -632,20 +632,32 @@
 ocker') 
-%7B%0A  
+return next();%0A%0A
   Docker
@@ -694,34 +694,32 @@
 tion(err) %7B%0A    
-  
 if (err) %7B%0A     
@@ -715,26 +715,24 @@
 rr) %7B%0A      
- 
- 
 var errMessa
@@ -767,18 +767,16 @@
  : err;%0A
-  
       bo
@@ -850,18 +850,16 @@
 ssage);%0A
-  
     %7D%0A  
@@ -864,18 +864,16 @@
     
-  
 next();%0A
     
@@ -872,50 +872,14 @@
 ();%0A
-  
   %7D);%0A
-  %7D else %7B%0A    return next();%0A  %7D%0A
 %7D%0A%0Af
@@ -944,21 +944,22 @@
   var is
-Local
+Remote
 Service 
@@ -965,10 +965,30 @@
  = !
+runConfig.service %7C%7C 
 !
-(
 runC
@@ -1004,11 +1004,16 @@
 vice
- &&
+.type %7C%7C
  run
@@ -1031,17 +1031,29 @@
 ice.type
-)
+ === 'remote'
 ;%0A  var 
@@ -1107,23 +1107,25 @@
 ;%0A  if (
+!
 is
-Local
+Remote
 Service 
@@ -1139,22 +1139,16 @@
 calRepo)
- %7B%0A   
  return 
@@ -1155,19 +1155,16 @@
 next();%0A
-  %7D
 %0A  RunLi
@@ -1261,24 +1261,16 @@
 if (err)
- %7B%0A     
  return 
@@ -1273,29 +1273,24 @@
 urn next();%0A
-    %7D
 %0A    if (!sv
@@ -1302,24 +1302,16 @@
 ig.name)
- %7B%0A     
  svcConf
@@ -1336,21 +1336,16 @@
 g.name;%0A
-    %7D
 %0A    doc
@@ -1533,16 +1533,17 @@
 ;%0A  if (
+!
 bosco.ex
@@ -1562,20 +1562,32 @@
 rvice)) 
-%7B%0A  
+return next();%0A%0A
   var de
@@ -1620,18 +1620,16 @@
 rvice);%0A
-  
   docker
@@ -1670,42 +1670,8 @@
 t);%0A
-  %7D else %7B%0A    return next();%0A  %7D%0A
 %7D%0A%0Af

Fix docker pull for remote docker projects.