'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();

exports.addCreateService = addCreateService;
exports.addUpdateService = addUpdateService;
exports.addCreateOrUpdateService = addCreateOrUpdateService;
exports.addStopService = addStopService;
exports.addRestartService = addRestartService;

var _monitorService = require('./monitor-service');

var _utils = require('../utils');

var _shellEscape = require('shell-escape');

var _shellEscape2 = _interopRequireDefault(_shellEscape);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function escapeEnv(env) {
  if (env instanceof Array) {
    return env.map(function (_env) {
      _env.value = (0, _shellEscape2.default)([_env.value]);

      return _env;
    });
  }

  return Object.keys(env).reduce(function (result, key) {
    result[key] = (0, _shellEscape2.default)([env[key]]);

    return result;
  }, {});
}

function addCreateService(taskList) {
  var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
      image = _ref.image,
      name = _ref.name,
      publishedPort = _ref.publishedPort,
      targetPort = _ref.targetPort,
      envFile = _ref.envFile,
      env = _ref.env,
      hostname = _ref.hostname,
      _ref$mode = _ref.mode,
      mode = _ref$mode === undefined ? 'replicated' : _ref$mode,
      replicas = _ref.replicas,
      _ref$constraints = _ref.constraints,
      constraints = _ref$constraints === undefined ? [] : _ref$constraints,
      _ref$endpointMode = _ref.endpointMode,
      endpointMode = _ref$endpointMode === undefined ? 'vip' : _ref$endpointMode,
      _ref$networks = _ref.networks,
      networks = _ref$networks === undefined ? [] : _ref$networks,
      _ref$updateFailureAct = _ref.updateFailureAction,
      updateFailureAction = _ref$updateFailureAct === undefined ? 'rollback' : _ref$updateFailureAct,
      _ref$updateParallelis = _ref.updateParallelism,
      updateParallelism = _ref$updateParallelis === undefined ? 0 : _ref$updateParallelis,
      _ref$updateDelay = _ref.updateDelay,
      updateDelay = _ref$updateDelay === undefined ? 0 : _ref$updateDelay;

  taskList.executeScript('Start2 ' + name, {
    script: (0, _utils.resolvePath)(__dirname, 'assets/create-service.sh'),
    vars: {
      name: name,
      publishedPort: publishedPort,
      targetPort: targetPort,
      envFile: envFile,
      env: escapeEnv(env),
      image: image,
      replicas: replicas,
      hostname: hostname,
      mode: mode,
      endpointMode: endpointMode,
      networks: networks,
      updateFailureAction: updateFailureAction,
      updateParallelism: updateParallelism,
      updateDelay: updateDelay / 1000 + 's',
      constraints: constraints
    }
  });

  return taskList;
  // return monitorServiceProgress(taskList);
}

function diffEnv(wantedEnv, _currentEnv) {
  var toAdd = [];
  var toRemove = [];

  var currentEnv = _currentEnv.reduce(function (result, env) {
    var _env$split = env.split('='),
        _env$split2 = _slicedToArray(_env$split, 2),
        name = _env$split2[0],
        value = _env$split2[1];

    result[name] = value;

    return result;
  }, {});

  var _iteratorNormalCompletion = true;
  var _didIteratorError = false;
  var _iteratorError = undefined;

  try {
    for (var _iterator = Object.entries(wantedEnv)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
      var _step$value = _slicedToArray(_step.value, 2),
          name = _step$value[0],
          value = _step$value[1];

      if (!(name in currentEnv) || currentEnv[name] !== value.toString()) {
        toAdd.push({ name: name, value: value });
      }
    }
  } catch (err) {
    _didIteratorError = true;
    _iteratorError = err;
  } finally {
    try {
      if (!_iteratorNormalCompletion && _iterator.return) {
        _iterator.return();
      }
    } finally {
      if (_didIteratorError) {
        throw _iteratorError;
      }
    }
  }

  var _iteratorNormalCompletion2 = true;
  var _didIteratorError2 = false;
  var _iteratorError2 = undefined;

  try {
    for (var _iterator2 = Object.entries(currentEnv)[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
      var _step2$value = _slicedToArray(_step2.value, 1),
          name = _step2$value[0];

      if (!(name in wantedEnv)) {
        toRemove.push({ name: name });
      }
    }
  } catch (err) {
    _didIteratorError2 = true;
    _iteratorError2 = err;
  } finally {
    try {
      if (!_iteratorNormalCompletion2 && _iterator2.return) {
        _iterator2.return();
      }
    } finally {
      if (_didIteratorError2) {
        throw _iteratorError2;
      }
    }
  }

  return {
    envAdd: toAdd,
    envRemove: toRemove
  };
}

function ifChanged(current, compareValue, newValue) {
  if (current !== compareValue) {
    console.log(current, compareValue, newValue);

    return typeof newValue === 'undefined' ? compareValue : newValue;
  }

  return null;
}

function addUpdateService(taskList, _ref2, currentService) {
  var name = _ref2.name,
      image = _ref2.image,
      env = _ref2.env,
      hostname = _ref2.hostname,
      endpointMode = _ref2.endpointMode,
      updateFailureAction = _ref2.updateFailureAction,
      updateParallelism = _ref2.updateParallelism,
      updateDelay = _ref2.updateDelay;
  var _currentService$Spec = currentService.Spec,
      EndpointSpec = _currentService$Spec.EndpointSpec,
      TaskTemplate = _currentService$Spec.TaskTemplate,
      UpdateConfig = _currentService$Spec.UpdateConfig;

  var containerSpec = TaskTemplate.ContainerSpec;

  var _diffEnv = diffEnv(env, containerSpec.Env),
      envAdd = _diffEnv.envAdd,
      envRemove = _diffEnv.envRemove;

  // TODO: skip running the script if there is nothing to update


  taskList.executeScript('Update ' + name, {
    script: (0, _utils.resolvePath)(__dirname, 'assets/update-service.sh'),
    vars: {
      image: ifChanged(containerSpec.Image, image),
      hostname: ifChanged(containerSpec.Hostname, hostname),
      envAdd: escapeEnv(envAdd),
      envRemove: envRemove,
      name: name,
      endpointMode: ifChanged(EndpointSpec.Mode, endpointMode),
      updateFailureAction: ifChanged(UpdateConfig.FailureAction, updateFailureAction),
      updateDelay: ifChanged(UpdateConfig.Delay, updateDelay * 1000000, updateDelay),
      updateParallelism: ifChanged(UpdateConfig.Parallelism, updateParallelism)
    }
  });

  return taskList;
  // return monitorServiceProgress(taskList);
}

function addCreateOrUpdateService(tasklist, options, currentService) {
  if (currentService) {
    return addUpdateService(tasklist, options, currentService);
  }

  return addCreateService(tasklist, options);
}

function addStopService(taskList, _ref3) {
  var name = _ref3.name;

  taskList.executeScript('Stop ' + name, {
    script: (0, _utils.resolvePath)(__dirname, 'assets/stop-service.sh'),
    vars: {
      name: name
    }
  });

  return taskList;
}

function addRestartService(taskList, _ref4) {
  var name = _ref4.name;

  taskList.executeScript('Restart ' + name, {
    script: (0, _utils.resolvePath)(__dirname, 'assets/restart-service.sh'),
    vars: {
      name: name
    }
  });
}
//# sourceMappingURL=index.js.map