'use strict';

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

var _http;

function _load_http() {
  return _http = _interopRequireDefault(require('http'));
}

var _uuid;

function _load_uuid() {
  return _uuid = _interopRequireDefault(require('uuid'));
}

var _opn;

function _load_opn() {
  return _opn = _interopRequireDefault(require('opn'));
}

var _os;

function _load_os() {
  return _os = _interopRequireDefault(require('os'));
}

var _chalk;

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

var _url;

function _load_url() {
  return _url = _interopRequireDefault(require('url'));
}

var _globalConfig;

function _load_globalConfig() {
  return _globalConfig = require('../../api/consumer/lib/global-config');
}

var _constants;

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

var _exceptions;

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

var _logger;

function _load_logger() {
  return _logger = _interopRequireDefault(require('../../logger/logger'));
}

var _generalError;

function _load_generalError() {
  return _generalError = _interopRequireDefault(require('../../error/general-error'));
}

var _analytics;

function _load_analytics() {
  return _analytics = require('../../analytics/analytics');
}

var _driver;

function _load_driver() {
  return _driver = require('../../driver');
}

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

var ERROR_RESPONSE = 500;

var DEFAULT_PORT = 8085;
var REDIRECT = 302;

function loginToBitSrc(port, suppressBrowserLaunch, npmrcPath, skipRegistryConfig) {
  var actualNpmrcPath = npmrcPath;
  return new Promise(function (resolve, reject) {
    var clientGeneratedId = (0, (_uuid || _load_uuid()).default)();
    var driver = (_driver || _load_driver()).Driver.load((_constants || _load_constants()).DEFAULT_LANGUAGE);
    if ((0, (_globalConfig || _load_globalConfig()).getSync)((_constants || _load_constants()).CFG_USER_TOKEN_KEY)) {
      // $FlowFixMe
      return resolve({
        isAlreadyLoggedIn: true
      });
    }
    var server = (_http || _load_http()).default.createServer(function (request, response) {
      var closeConnection = function closeConnection(statusCode) {
        if (statusCode) response.statusCode = statusCode;
        response.end();
        server.close();
      };
      if (request.method !== 'GET') {
        (_logger || _load_logger()).default.error('received non get request, closing connection');
        closeConnection();
        reject(new (_exceptions || _load_exceptions()).LoginFailed());
      }
      try {
        var _ref = (_url || _load_url()).default.parse(request.url, true).query || {},
            clientId = _ref.clientId,
            redirectUri = _ref.redirectUri,
            _username = _ref.username,
            token = _ref.token;

        var writeToNpmrcError = false;
        if (clientGeneratedId !== clientId) {
          (_logger || _load_logger()).default.error(`clientId mismatch, expecting: ${clientGeneratedId} got ${clientId}`);
          closeConnection(ERROR_RESPONSE);
          reject(new (_exceptions || _load_exceptions()).LoginFailed());
        }
        (0, (_globalConfig || _load_globalConfig()).setSync)((_constants || _load_constants()).CFG_USER_TOKEN_KEY, token);
        if (!skipRegistryConfig) {
          try {
            actualNpmrcPath = driver.npmLogin(token, npmrcPath, (0, (_globalConfig || _load_globalConfig()).getSync)((_constants || _load_constants()).CFG_REGISTRY_URL_KEY) || (_constants || _load_constants()).DEFAULT_REGISTRY_URL);
          } catch (e) {
            actualNpmrcPath = e.path;
            writeToNpmrcError = true;
          }
        }

        response.writeHead(REDIRECT, {
          Location: redirectUri
        });
        closeConnection();
        resolve({
          username: _username,
          npmrcPath: actualNpmrcPath,
          writeToNpmrcError
        });
      } catch (err) {
        (_logger || _load_logger()).default.err(`err on login: ${err}`);
        closeConnection(ERROR_RESPONSE);
        reject(new (_exceptions || _load_exceptions()).LoginFailed());
      }
    });

    (_analytics || _load_analytics()).Analytics.addBreadCrumb('login', `initializing login server  on port: ${port || DEFAULT_PORT}`);
    server.listen(port || DEFAULT_PORT, function (err) {
      if (err) {
        (_logger || _load_logger()).default.error('something bad happened', err);
        reject(new (_exceptions || _load_exceptions()).LoginFailed());
      }

      var encoded = encodeURI(`${(0, (_globalConfig || _load_globalConfig()).getSync)((_constants || _load_constants()).CFG_HUB_LOGIN_KEY) || (_constants || _load_constants()).DEFAULT_HUB_LOGIN}?port=${port || DEFAULT_PORT}&clientId=${clientGeneratedId}&responseType=token&deviceName=${(_os || _load_os()).default.hostname()}&os=${process.platform}`);
      if (!suppressBrowserLaunch) {
        console.log((_chalk || _load_chalk()).default.yellow(`Your browser has been opened to visit:\n${encoded}`)); // eslint-disable-line no-console
        (0, (_opn || _load_opn()).default)(encoded);
      } else {
        console.log((_chalk || _load_chalk()).default.yellow(`Go to the following link in your browser::\n${encoded}`)); // eslint-disable-line no-console
      }
    });

    server.on('error', function (e) {
      if (e.code === 'EADDRINUSE') {
        reject(new (_generalError || _load_generalError()).default(`port: ${e.port} alredy in use, please run bit login --port <port>`));
      }
      reject(e);
    });
    return {};
  });
}