'use strict';

var _promise = require('babel-runtime/core-js/promise');

var _promise2 = _interopRequireDefault(_promise);

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

var hosts = require('../util/hosts');
var chalk = require('chalk');
var config = require('./config');
var debugServer = require('../server');
var boxen = require('boxen');

var detect = require('detect-port');
var headless = require('../server/headless');
var qrcode = require('qrcode-terminal-alpha');

var _require = require('../util/logger'),
    logger = _require.logger;

// 1 - start with debugserver only
// 3 - start with debugserver with headless server
// 5 - start with debugserver with building
// 7 - start with debugserver with headless server and building


var startPath = 1;

function resolveBundleUrl(bundlePath, ip, port) {
  return 'http://' + ip + ':' + port + '/' + config.bundleDir + '/' + bundlePath.replace(/\.(we|vue)$/, '.js');
}

function isUrl(str) {
  return (/^https?:\/\//.test(str)
  );
}

function resolveRealUrl(url) {
  return url.replace(/^(https?:\/\/)([^/:]+)(?=:\d+|\/)/, function (m, a, b) {
    if (!/\d+\.\d+\.\d+\.\d+/.test(a)) {
      return a + hosts.findRealHost(b);
    } else {
      return m;
    }
  });
}

function resolveConnectUrl(config) {
  var host = config.ip + ':' + config.port;
  config.connectUrl = config.connectUrl || 'http://' + host + '/devtool_fake.html?_atom_devtool=ws://' + host + '/debugProxy/native/{channelId}';
  config.debugUrl = config.debugUrl || 'http://' + host + '/debug.html?channelId={channelId}';
}

exports.startServerAndLaunch = function (ip, port, manual, cb) {
  var _this = this;

  this.startServer(ip, port).then(function () {
    cb && cb('ws://' + ip + ':' + port);
    if (!manual) _this.launch(ip, port);
  });
};

exports.startServer = function (ip, port) {
  return new _promise2.default(function (resolve, reject) {
    var inUse = config.inUse;
    var message = chalk.green('Start debugger server!');
    if (inUse) {
      message += ' ' + chalk.red('(on port ' + inUse.open + ',' + (' because ' + inUse.old + ' is already in use)'));
    }
    message += '\n\n';
    message += '- ' + chalk.bold('Websocket Address For Native: ') + ' ws://' + ip + ':' + port + '\n';
    debugServer.start(port, function () {
      if (config.enableStartMessage) {
        logger.log(boxen(message, {
          padding: 1,
          borderColor: 'green',
          margin: 1
        }));
      }
      resolve();
    });
    if (config.enableStartMessage) {
      qrcode.generate('{"debug":"ws://' + ip + ':' + port + '"}', { small: true });
    }
  });
};

exports.launch = function (ip, port) {
  if (config.enableStartMessage) {
    logger.info('Launching Dev Tools...');
  }
  if (config.enableHeadless) {
    startPath += 2;
    // Check whether the port is occupied
    detect(config.remoteDebugPort).then(function (open) {
      if (+config.remoteDebugPort !== open) {
        headless.closeHeadless();
        if (config.enableStartMessage) {
          logger.info('Starting inspector on port ' + open + ', because ' + config.remoteDebugPort + ' is already in use');
        }
      } else {
        if (config.enableStartMessage) {
          logger.info('Starting inspector on port ' + open);
        }
      }
      config.remoteDebugPort = open;
      headless.launchHeadless(config.ip + ':' + config.port, open);
    });
  }
};config;

exports.resolveBundlesAndEntry = function (entry, bundles, ip, port) {
  var entryUrl = void 0;
  var bundleUrls = bundles.map(function (b) {
    return resolveBundleUrl(b, ip, port);
  });
  if (isUrl(entry)) {
    entryUrl = resolveRealUrl(entry);
    entryUrl = entryUrl.replace(/127\.0\.0\.1/g, ip);
    bundleUrls.push(entryUrl);
  }
  return bundleUrls;
};

exports.start = function (target, config, cb) {
  resolveConnectUrl(config);
  if (isUrl(target)) {
    var bundleUrls = this.resolveBundlesAndEntry(target, [], config.ip, config.port);
    config.bundleUrls = bundleUrls;
    this.startServerAndLaunch(config.ip, config.port, config.manual, cb);
  } else {
    this.startServerAndLaunch(config.ip, config.port, config.manual, cb);
  }
};