"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));

var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));

var _ = require('underscore'),
    processHelper = require('./process-helper.js'),
    selenium = require('selenium-standalone'),
    booleanHelper = require('./boolean-helper'),
    log = require('./log');

var Selenium =
/**
 * Selenium Constructor
 *
 * @param {Object} options
 * @api public
 */
function Selenium(_options) {
  var _this = this;

  (0, _classCallCheck2["default"])(this, Selenium);
  (0, _defineProperty2["default"])(this, "install", function (callback) {
    var ProgressBar = require('progress');

    var bar;
    var firstProgress = true;
    Selenium.installCallback = callback;

    if (_this.options.offline) {
      log.debug('[chimp][selenium]', 'Offline mode enabled, Chimp will not attempt to install Selenium & Drivers');
      callback();
      return;
    }

    log.debug('[chimp][selenium]', 'Installing Selenium + drivers if needed');
    _this.seleniumStandaloneOptions.progressCb = progressCb;
    selenium.install(_this.seleniumStandaloneOptions, function (e, r) {
      if (e && e.message.match(/Error: getaddrinfo ENOTFOUND/)) {
        log.debug('[chimp][selenium]', e.message);
        log.info('[chimp][selenium] Detected a connection error in selenium-standalone. Are you offline?');
        log.info('[chimp][selenium] Consider using the --offline option to explicitly skip installing Selenium & drivers.');
        log.info('[chimp][selenium] Attempting to continue...');
        Selenium.installCallback(null, r);
      } else {
        Selenium.installCallback(e, r);
      }
    });

    function progressCb(total, progress, chunk) {
      if (firstProgress) {
        firstProgress = false;
      }

      bar = bar || new ProgressBar('selenium-standalone installation [:bar] :percent :etas', {
        total: total,
        complete: '=',
        incomplete: ' ',
        width: 20
      });
      bar.tick(chunk);
    }
  });
  (0, _defineProperty2["default"])(this, "start", function (callback) {
    var self = _this;
    var port = self.options.port;
    Selenium.startCallback = callback;
    log.debug('[chimp][selenium]', 'Start');

    if (self.child) {
      log.debug('[chimp][selenium]', 'Already running, doing nothing');
      callback(null);
      return;
    }

    self.install(function (error) {
      if (error) {
        log.error('[selenium]', error);
        Selenium.startCallback(error);
        return;
      }

      if (!self.seleniumStandaloneOptions.seleniumArgs) {
        self.seleniumStandaloneOptions.seleniumArgs = [];
      }

      self.seleniumStandaloneOptions.seleniumArgs.push('-port', port);

      if (process.env['chimp.log'] === 'verbose' || process.env['chimp.log'] === 'debug') {
        self.options.seleniumDebug = true;
      }

      if (self.options.seleniumDebug) {
        self.seleniumStandaloneOptions.seleniumArgs.push('-debug');
      }

      log.debug("\n[chimp][selenium] hub can be seen at http://localhost:".concat(port, "/wd/hub"));
      selenium.start(self.seleniumStandaloneOptions, function (error, seleniumChild) {
        self.child = seleniumChild;

        if (error) {
          Selenium.startCallback(error);
          return;
        }

        if (self.options.seleniumDebug) {
          processHelper.logOutputs('selenium', self.child);
        }

        process.on('exit', function () {
          log.debug('[chimp][selenium] process exit event detected. Stopping process');
          self.stop(function () {
            log.debug('[chimp][selenium] process exit event stop complete');
          });
        });
        Selenium.startCallback(null);
      });
    });
  });
  (0, _defineProperty2["default"])(this, "stop", function (callback) {
    var self = _this;
    Selenium.stopCallback = callback;

    if (self.child) {
      log.debug('[chimp][selenium] killing active session');
      var options = {
        child: self.child,
        prefix: 'selenium',
        signal: 'SIGINT'
      };
      log.debug('[chimp][selenium] stopping process');
      processHelper.kill(options, function (err, res) {
        self.child = null;
        Selenium.stopCallback(err, res);
      });
    } else {
      log.debug('[chimp][selenium] no process to kill');
      Selenium.stopCallback(null);
    }
  });
  (0, _defineProperty2["default"])(this, "interrupt", function (callback) {
    log.debug('[chimp][selenium] interrupt called');

    if (!_this.options.watch || !!_this.options['clean-selenium-server']) {
      _this.stop(callback);
    } else {
      log.debug('[chimp][selenium] interrupt is not killing selenium because ' + 'clean-selenium-server not set');
      callback(null);
    }
  });

  if (!_options) {
    throw new Error('options is required');
  }

  if (booleanHelper.isFalsey(_options.port)) {
    throw new Error('options.port is required');
  }

  this.options = _.clone(_options);
  this.seleniumStandaloneOptions = _options.seleniumStandaloneOptions;

  if (!this.options['clean-selenium-server']) {
    // poor-man's singleton is enough for our needs
    if ((0, _typeof2["default"])(Selenium.instance) === 'object') {
      log.debug('[chimp][selenium]', 'Selenium object already exists, not creating a new one');
      return Selenium.instance;
    }

    log.debug('[chimp][selenium]', 'Selenium object created');
    Selenium.instance = this;
  }

  this.options.port = String(_options.port);
  this.child = null;
}
/**
 * Installs Selenium and drivers.
 *
 * @param {Function} callback
 * @api public
 */
;

module.exports = Selenium;