'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.run = exports.requireLockfile = undefined;

var _promise;

function _load_promise() {
  return _promise = _interopRequireDefault(require('babel-runtime/core-js/promise'));
}

var _keys;

function _load_keys() {
  return _keys = _interopRequireDefault(require('babel-runtime/core-js/object/keys'));
}

var _asyncToGenerator2;

function _load_asyncToGenerator() {
  return _asyncToGenerator2 = _interopRequireDefault(require('babel-runtime/helpers/asyncToGenerator'));
}

// Prompt user with Inquirer
let prompt = (() => {
  var _ref = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (choices) {
    let pageSize;
    if (process.stdout instanceof tty.WriteStream) {
      pageSize = process.stdout.rows - 2;
    }
    const answers = yield (_inquirer || _load_inquirer()).default.prompt([{
      name: 'packages',
      type: 'checkbox',
      message: 'Choose which packages to update.',
      choices: choices,
      pageSize: pageSize,
      validate: function validate(answer) {
        return !!answer.length || 'You must choose at least one package.';
      }
    }]);
    return answers.packages;
  });

  return function prompt(_x) {
    return _ref.apply(this, arguments);
  };
})();

let run = exports.run = (() => {
  var _ref2 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (config, reporter, flags, args) {
    const lockfile = yield (_wrapper || _load_wrapper()).default.fromDirectory(config.cwd);
    const install = new (_install || _load_install()).Install(flags, config, reporter, lockfile);
    const deps = yield (_packageRequest || _load_packageRequest()).default.getOutdatedPackages(lockfile, install, config, reporter);

    if (!deps.length) {
      reporter.success(reporter.lang('allDependenciesUpToDate'));
      return;
    }

    const getNameFromHint = function getNameFromHint(hint) {
      return hint ? `${hint}Dependencies` : 'dependencies';
    };

    const maxLengthArr = { name: 0, current: 0, latest: 0 };
    deps.forEach(function (dep) {
      return ['name', 'current', 'latest'].forEach(function (key) {
        maxLengthArr[key] = Math.max(maxLengthArr[key], dep[key].length);
      });
    });

    // Depends on maxLengthArr
    const addPadding = function addPadding(dep) {
      return function (key) {
        return `${dep[key]}${' '.repeat(maxLengthArr[key] - dep[key].length)}`;
      };
    };

    const colorizeName = function colorizeName(_ref3) {
      let current = _ref3.current,
          wanted = _ref3.wanted;
      return current === wanted ? reporter.format.yellow : reporter.format.red;
    };

    const colorizeDiff = function colorizeDiff(from, to) {
      const parts = to.split('.');
      const fromParts = from.split('.');

      const index = parts.findIndex(function (part, i) {
        return part !== fromParts[i];
      });
      const splitIndex = index >= 0 ? index : parts.length;

      const colorized = reporter.format.green(parts.slice(splitIndex).join('.'));
      return parts.slice(0, splitIndex).concat(colorized).join('.');
    };

    const makeRow = function makeRow(dep) {
      const padding = addPadding(dep);
      const name = colorizeName(dep)(padding('name'));
      const current = reporter.format.blue(padding('current'));
      const latest = colorizeDiff(dep.current, padding('latest'));
      const url = reporter.format.cyan(dep.url);
      return `${name}  ${current}  ❯  ${latest}  ${url}`;
    };

    const groupedDeps = deps.reduce(function (acc, dep) {
      const hint = dep.hint,
            name = dep.name,
            latest = dep.latest;

      const key = getNameFromHint(hint);
      const xs = acc[key] || [];
      acc[key] = xs.concat({
        name: makeRow(dep),
        value: dep,
        short: `${name}@${latest}`
      });
      return acc;
    }, {});

    const flatten = function flatten(xs) {
      return xs.reduce(function (ys, y) {
        return ys.concat(Array.isArray(y) ? flatten(y) : y);
      }, []);
    };

    const choices = (0, (_keys || _load_keys()).default)(groupedDeps).map(function (key) {
      return [new (_inquirer || _load_inquirer()).default.Separator(reporter.format.bold.underline.green(key)), groupedDeps[key], new (_inquirer || _load_inquirer()).default.Separator(' ')];
    });

    const answers = yield prompt(flatten(choices));

    const getName = function getName(_ref4) {
      let name = _ref4.name;
      return name;
    };
    const isHint = function isHint(x) {
      return function (_ref5) {
        let hint = _ref5.hint;
        return hint === x;
      };
    };

    yield [null, 'dev', 'optional', 'peer'].reduce((() => {
      var _ref6 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (promise, hint) {
        // Wait for previous promise to resolve
        yield promise;
        // Reset dependency flags
        flags.dev = hint === 'dev';
        flags.peer = hint === 'peer';
        flags.optional = hint === 'optional';

        const deps = answers.filter(isHint(hint)).map(getName);
        if (deps.length) {
          reporter.info(reporter.lang('updateInstalling', getNameFromHint(hint)));
          const add = new (_add || _load_add()).Add(deps, flags, config, reporter, lockfile);
          return yield add.init();
        }
        return (_promise || _load_promise()).default.resolve();
      });

      return function (_x6, _x7) {
        return _ref6.apply(this, arguments);
      };
    })(), (_promise || _load_promise()).default.resolve());
  });

  return function run(_x2, _x3, _x4, _x5) {
    return _ref2.apply(this, arguments);
  };
})();

exports.setFlags = setFlags;

var _inquirer;

function _load_inquirer() {
  return _inquirer = _interopRequireDefault(require('inquirer'));
}

var _packageRequest;

function _load_packageRequest() {
  return _packageRequest = _interopRequireDefault(require('../../package-request.js'));
}

var _add;

function _load_add() {
  return _add = require('./add.js');
}

var _install;

function _load_install() {
  return _install = require('./install.js');
}

var _wrapper;

function _load_wrapper() {
  return _wrapper = _interopRequireDefault(require('../../lockfile/wrapper.js'));
}

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

const tty = require('tty');

const requireLockfile = exports.requireLockfile = true;

function setFlags(commander) {
  commander.usage('upgrade-interactive');
  commander.option('-E, --exact', 'install exact version');
  commander.option('-T, --tilde', 'install most recent release with the same minor version');
}