/*
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

'use strict';

var assert = require('assert');
var bunyan = require('bunyan');
var Executor = require('./executor.js');
var findImage = require('./docker').findImage;

module.exports = function(config, logger) {
  logger = logger || bunyan.createLogger({name: 'docker-registry-container'});
  var executor = new Executor(config);

  /**
   * build the container 
   * system - the system definition
   * cdef - contianer definition block
   * out - ouput stream 
   * cb - complete callback
   */
  var build = function build(mode, system, containerDef, out, cb) {
    logger.info('building');
    out.stdout('--> building');

    var name = containerDef.specific.name;

    if (!name) {
      return cb(new Error('missing name for definition ' + containerDef.id));
    }

    var pull = 'docker pull ' + name;
    var tag = 'docker tag ' + name + ' ' + system.name + '/' + name;

    if (mode === 'preview') {
      out.preview({ host: target.privateIpAddress || 'localhost', cmd: pull });
      out.preview({ host: target.privateIpAddress || 'localhost', cmd: tag });
      return cb();
    }

    executor.exec(null, pull, out, function(err) {
      if (err) {
        return cb(err);
      }

      executor.exec(null, tag, out, function(err) {

        if (err) {
          return cb(err);
        }

        findImage(system.name + '/' + name, function(err, image) {
          if (err) {
            return cb(err);
          }

          cb(null, {
            dockerImageId: image.Id
          });
        });
      });
    });
  };



  /**
   * deploy the continaer
   * target - target to deploy to
   * system - the target system defintinion
   * cdef - the contianer definition
   * container - the container as defined in the system topology
   * out - ouput stream 
   * cb - complete callback
   */
  var deploy = function deploy(mode, target, system, containerDef, container, out, cb) {
    cb();
  };



  /**
   * undeploy the container from the target
   * target - target to deploy to
   * system - the target system defintinion
   * cdef - the contianer definition
   * container - the container as defined in the system topology
   * out - ouput stream 
   * cb - complete callback
   */
  var undeploy = function undeploy(mode, target, system, containerDef, container, out, cb) {
    cb();
  };



  /**
   * start the container on the target
   * target - target to deploy to
   * system - the target system defintinion
   * cdef - the contianer definition
   * container - the container as defined in the system topology
   * out - ouput stream 
   * cb - complete callback
   */
  var start = function start(mode, target, system, containerDef, container, out, cb) {
    logger.info('starting');
    out.stdout('--> starting');

    var name = containerDef.specific.name;
    var args = containerDef.specific.execute.args || '';
    var exec = containerDef.specific.execute.exec || '';
    var cmd = 'docker run ' + args + ' ' + name + ' ' + exec;

    if (mode === 'preview') {
      out.preview({ host: target.privateIpAddress || 'localhost', cmd: cmd });
      return cb();
    }

    executor.exec(target.privateIpAddress, cmd, out, cb);
  };



  /**
   * stop the container on the target
   * target - target to deploy to
   * system - the target system defintinion
   * cdef - the contianer definition
   * container - the container as defined in the system topology
   * out - ouput stream 
   * cb - complete callback
   */
  var stop = function stop(mode, target, system, containerDef, container, out, cb) {
    logger.info('stopping');
    out.stdout('stopping');
    cb();
  };



  /**
   * link the container to the target
   * target - target to deploy to
   * system - the target system defintinion
   * cdef - the contianer definition
   * container - the container as defined in the system topology
   * out - ouput stream 
   * cb - complete callback
   */
  var link = function link(mode, target, system, containerDef, container, out, cb) {
    logger.info('linking');
    out.stdout('linking');
    cb();
  };



  /**
   * unlink the container from the target
   * target - target to deploy to
   * system - the target system defintinion
   * cdef - the contianer definition
   * container - the container as defined in the system topology
   * out - ouput stream 
   * cb - complete callback
   */
  var unlink = function unlink(mode, target, system, containerDef, container, out, cb) {
    logger.info('unlinking');
    out.stdout('unlinking');
    cb();
  };



  return {
    build: build,
    deploy: deploy,
    start: start,
    stop: stop,
    link: link,
    unlink: unlink,
    undeploy: undeploy,
    add: deploy,
    remove: undeploy
  };
};


@@ -1508,53 +1508,168 @@
     
-var pull = 'docker pull ' + name;%0A    var tag
+if (containerDef.specific.execute) %7B%0A      return cb(new Error('missing execute block in ' + containerDef.id + ' container definition'));%0A    %7D%0A%0A    var pullCmd
  = '
@@ -1675,19 +1675,20 @@
 'docker 
-tag
+pull
  ' + nam
@@ -1688,24 +1688,31 @@
 ' + name
- + ' ' +
+;%0A    var tag =
  system.
@@ -1728,228 +1728,75 @@
 ' + 
-name;%0A%0A    if (mode === 'preview') %7B%0A      out.preview(%7B host: target.privateIpAddress %7C%7C 'localhost', cmd: pull %7D);%0A      out.preview(%7B host: target.privateIpAddress %7C%7C 'localhost', cmd: tag %7D);%0A      return cb();%0A    %7D
+containerDef.id;%0A    var tagCmd = 'docker tag ' + name + ' ' + tag;
 %0A%0A  
@@ -1821,16 +1821,19 @@
 ll, pull
+Cmd
 , out, f
@@ -1926,16 +1926,19 @@
 ull, tag
+Cmd
 , out, f
@@ -2031,32 +2031,11 @@
 age(
-system.name + '/' + name
+tag
 , fu
@@ -2173,16 +2173,43 @@
 image.Id
+,%0A            imageTag: tag
 %0A       

Use the containerDef id for tagging and not the registry name.