'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = checkVersionCompatibility;
exports.checkVersionCompatibilityOnTheServer = checkVersionCompatibilityOnTheServer;

var _semver;

function _load_semver() {
  return _semver = _interopRequireWildcard(require('semver'));
}

var _chalk;

function _load_chalk() {
  return _chalk = _interopRequireDefault(require('chalk'));
}

var _constants;

function _load_constants() {
  return _constants = require('../../constants');
}

var _loader;

function _load_loader() {
  return _loader = _interopRequireDefault(require('../../cli/loader/loader'));
}

var _exceptions;

function _load_exceptions() {
  return _exceptions = require('./exceptions');
}

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

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

var createMajorMessage = function createMajorMessage(remoteVersion, currentVersion) {
  return (_chalk || _load_chalk()).default.red(`Fatal: There is a mismatch between the remote server version - "${remoteVersion}" and your bit version - "${currentVersion}", please update\n`);
};


var createMinorMessage = function createMinorMessage(remoteVersion, currentVersion) {
  return (_chalk || _load_chalk()).default.yellow(`Warning: There is a mismatch between the remote server version - "${remoteVersion}" and your bit version - "${currentVersion}", please update\n`);
};

/**
 * before version 14.x there was no way for the server to throw a custom error regarding the
 * old client version. what we can do is throwing a generic error, which the client will
 * catch as UnexpectedNetworkError. Since the client shows an error itself (see
 * checkVersionCompatibility()) the user will get both errors: checkVersionCompatibility()
 * and checkVersionCompatibilityOnTheServer().
 *
 * Since version 14.x a new Error has created OldClientVersion, when the client uses a version
 * equal or bigger than 14.x it's easier to show the entire error using that class.
 */
var throwErrorFromServerSinceVersion = 14;

function checkVersionCompatibility(remoteVersion) {
  // In case the client is newer than the server version don't check computability
  // (Should be change in the future, but right now we won't release a client which we don't support
  //  on the server)
  if ((_semver || _load_semver()).gte((_constants || _load_constants()).BIT_VERSION, remoteVersion)) {
    return;
  }

  var remoteMajor = (_semver || _load_semver()).major(remoteVersion);
  var remoteMinor = (_semver || _load_semver()).minor(remoteVersion);
  var remotePatch = (_semver || _load_semver()).patch(remoteVersion);
  var localMajor = (_semver || _load_semver()).major((_constants || _load_constants()).BIT_VERSION);
  var localMinor = (_semver || _load_semver()).minor((_constants || _load_constants()).BIT_VERSION);
  var localPatch = (_semver || _load_semver()).patch((_constants || _load_constants()).BIT_VERSION);

  if (remoteMajor > localMajor) {
    if (localMajor < throwErrorFromServerSinceVersion) return;
    (_loader || _load_loader()).default.stop();
    console.log(createMajorMessage(remoteVersion, (_constants || _load_constants()).BIT_VERSION)); // eslint-disable-line
    (_loader || _load_loader()).default.start();
    return;
  }

  if (remoteMinor > localMinor) {
    (_loader || _load_loader()).default.stop();
    console.log(createMajorMessage(remoteVersion, (_constants || _load_constants()).BIT_VERSION)); // eslint-disable-line
    (_loader || _load_loader()).default.start();
    return;
  }

  if (remotePatch > localPatch) {
    (_loader || _load_loader()).default.stop();
    console.log(createMinorMessage(remoteVersion, (_constants || _load_constants()).BIT_VERSION)); // eslint-disable-line
    (_loader || _load_loader()).default.start();
  }
}

/**
 * throw error when the server has a major version bigger than the client.
 *
 * we're trying to be backward compatible whenever possible, however, to be forward compatible
 * is much more difficult.
 * It's safer to not let an old client interact with the server at all than enabling some commands
 * and blocking others per version.
 * Imagine when a migration script is written (e.g. when a model field is changed) and it updates
 * some hashes of the components from the old version. If a client doesn't update its version and
 * is using an old version, the flow will break sooner or later with hash-not-found exception
 */
function checkVersionCompatibilityOnTheServer(clientVersion) {
  var clientMajor = (_semver || _load_semver()).major(clientVersion);
  var localMajor = (_semver || _load_semver()).major((_constants || _load_constants()).BIT_VERSION);
  var oldClientVersionMessageUntilV14 = 'Please update your Bit client.\nFor additional information: https://docs.bitsrc.io/docs/latest-version.html';
  var oldClientVersionMessageAfterV14 = function oldClientVersionMessageAfterV14() {
    return `Fatal: Bit client - server version mismatch. Using "${clientVersion}" Local version to communicate with "${(_constants || _load_constants()).BIT_VERSION}" on the Remove Server. Please update your Bit client.
For additional information: https://docs.bitsrc.io/docs/latest-version.html`;
  };

  if (localMajor > clientMajor) {
    if (clientMajor >= throwErrorFromServerSinceVersion) {
      // since version 14.x a new Error class has been created "OldClientVersion", use it.
      throw new (_exceptions || _load_exceptions()).OldClientVersion(oldClientVersionMessageAfterV14());
    }
    throw new Error(oldClientVersionMessageUntilV14);
  }
}