'use strict';

var _regenerator;

function _load_regenerator() {
  return _regenerator = _interopRequireDefault(require('babel-runtime/regenerator'));
}

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _serializeError;

function _load_serializeError() {
  return _serializeError = _interopRequireDefault(require('serialize-error'));
}

var _path;

function _load_path() {
  return _path = _interopRequireDefault(require('path'));
}

var _objectHash;

function _load_objectHash() {
  return _objectHash = _interopRequireDefault(require('object-hash'));
}

var _uniqid;

function _load_uniqid() {
  return _uniqid = _interopRequireDefault(require('uniqid'));
}

var _yn;

function _load_yn() {
  return _yn = _interopRequireDefault(require('yn'));
}

var _ramda;

function _load_ramda() {
  return _ramda = _interopRequireDefault(require('ramda'));
}

var _os;

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

var _lodash;

function _load_lodash() {
  return _lodash = _interopRequireDefault(require('lodash.omitby'));
}

var _child_process;

function _load_child_process() {
  return _child_process = require('child_process');
}

var _globalConfig;

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

var _prompts;

function _load_prompts() {
  return _prompts = require('../prompts');
}

var _constants;

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

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

function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var LEVEL = {
  DEBUG: 'debug',
  INFO: 'info',
  WARNING: 'warning',
  ERROR: 'error',
  FATAL: 'fatal'
};

var Breadcrumb = function Breadcrumb(category, message, data) {
  _classCallCheck(this, Breadcrumb);

  this.category = category;
  this.message = message;
  this.data = data;
};

var Analytics = function () {
  function Analytics() {
    _classCallCheck(this, Analytics);
  }

  _createClass(Analytics, null, [{
    key: 'getID',
    value: function getID() {
      var id = (0, (_globalConfig || _load_globalConfig()).getSync)((_constants || _load_constants()).CFG_ANALYTICS_USERID_KEY);
      if (id) return id;
      var newId = (0, (_uniqid || _load_uniqid()).default)();
      (0, (_globalConfig || _load_globalConfig()).setSync)((_constants || _load_constants()).CFG_ANALYTICS_USERID_KEY, newId);
      return newId;
    }
  }, {
    key: 'promptAnalyticsIfNeeded',
    value: function promptAnalyticsIfNeeded(cmd) {
      function shouldPromptForAnalytics() {
        // do not prompt analytics approval for bit config command (so you can configure it in CI envs)
        if (cmd.length && cmd[0] !== 'config') {
          var analyticsReporting = (0, (_globalConfig || _load_globalConfig()).getSync)((_constants || _load_constants()).CFG_ANALYTICS_REPORTING_KEY);
          var errorReporting = (0, (_globalConfig || _load_globalConfig()).getSync)((_constants || _load_constants()).CFG_ANALYTICS_ERROR_REPORTS_KEY);
          return (_ramda || _load_ramda()).default.isNil(analyticsReporting) && (_ramda || _load_ramda()).default.isNil(errorReporting);
        }
        return false;
      }

      if (shouldPromptForAnalytics()) {
        var uniqId = (0, (_uniqid || _load_uniqid()).default)();
        if (!(0, (_globalConfig || _load_globalConfig()).getSync)((_constants || _load_constants()).CFG_ANALYTICS_USERID_KEY)) (0, (_globalConfig || _load_globalConfig()).setSync)((_constants || _load_constants()).CFG_ANALYTICS_USERID_KEY, uniqId);
        return (0, (_prompts || _load_prompts()).analyticsPrompt)().then(function (_ref) {
          var analyticsResponse = _ref.analyticsResponse;

          (0, (_globalConfig || _load_globalConfig()).setSync)((_constants || _load_constants()).CFG_ANALYTICS_REPORTING_KEY, (0, (_yn || _load_yn()).default)(analyticsResponse));
          if (!(0, (_yn || _load_yn()).default)(analyticsResponse)) {
            return (0, (_prompts || _load_prompts()).errorReportingPrompt)().then(function (_ref2) {
              var errResponse = _ref2.errResponse;

              return (0, (_globalConfig || _load_globalConfig()).setSync)((_constants || _load_constants()).CFG_ANALYTICS_ERROR_REPORTS_KEY, (0, (_yn || _load_yn()).default)(errResponse));
            });
          }
          return Promise.resolve();
        });
      }
      return Promise.resolve();
    }
  }, {
    key: '_hashFlags',
    value: function _hashFlags(flags) {
      var hashedFlags = {};
      var nilOrFalse = function nilOrFalse(val) {
        return (_ramda || _load_ramda()).default.isNil(val) || val === false;
      };
      var filteredFlags = (0, (_lodash || _load_lodash()).default)(flags, nilOrFalse);
      if (this.anonymous && !(_ramda || _load_ramda()).default.isEmpty(filteredFlags)) {
        Object.keys(filteredFlags).forEach(function (key) {
          if (typeof flags[key] === 'boolean') {
            hashedFlags[key] = flags[key];
          } else {
            hashedFlags[key] = (0, (_objectHash || _load_objectHash()).default)(flags[key]);
          }
        });
        return hashedFlags;
      }
      return filteredFlags;
    }
  }, {
    key: 'init',
    value: function init(command, flags, args, version) {
      this.anonymous = (0, (_yn || _load_yn()).default)((0, (_globalConfig || _load_globalConfig()).getSync)((_constants || _load_constants()).CFG_ANALYTICS_ANONYMOUS_KEY), { default: true });
      this.command = command;
      this.flags = this._hashFlags(flags);
      this.release = version;
      this.args = this.anonymous ? (0, (_objectHash || _load_objectHash()).default)(args) : args;
      this.nodeVersion = process.version;
      this.os = process.platform;
      this.level = LEVEL.INFO;
      this.username = !this.anonymous ? (0, (_globalConfig || _load_globalConfig()).getSync)((_constants || _load_constants()).CFG_USER_EMAIL_KEY) || (0, (_globalConfig || _load_globalConfig()).getSync)((_constants || _load_constants()).CFG_USER_NAME_KEY) || (_os || _load_os()).default.hostname() || this.getID() : this.getID();
      this.analytics_usage = (0, (_yn || _load_yn()).default)((0, (_globalConfig || _load_globalConfig()).getSync)((_constants || _load_constants()).CFG_ANALYTICS_REPORTING_KEY), { default: false });
      this.error_usage = this.analytics_usage ? true : (0, (_yn || _load_yn()).default)((0, (_globalConfig || _load_globalConfig()).getSync)((_constants || _load_constants()).CFG_ANALYTICS_ERROR_REPORTS_KEY), { default: false });
      this.environment = (0, (_globalConfig || _load_globalConfig()).getSync)((_constants || _load_constants()).CFG_ANALYTICS_ENVIRONMENT_KEY) || (_constants || _load_constants()).DEFAULT_BIT_ENV;
    }
  }, {
    key: 'sendData',
    value: function () {
      var _ref3 = _asyncToGenerator( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee() {
        var forked;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                if (this.analytics_usage || this.error_usage && !this.success) {
                  forked = (0, (_child_process || _load_child_process()).fork)((_path || _load_path()).default.join(__dirname, 'analytics-sender.js'), { silent: true });

                  forked.send(this.toObject());
                }

                return _context.abrupt('return', Promise.resolve());

              case 2:
              case 'end':
                return _context.stop();
            }
          }
        }, _callee, this);
      }));

      function sendData() {
        return _ref3.apply(this, arguments);
      }

      return sendData;
    }()
  }, {
    key: 'setError',
    value: function setError() {
      var level = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : LEVEL.ERROR;
      var err = arguments[1];

      this.level = level;
      this.error = (0, (_serializeError || _load_serializeError()).default)(err);
      this.success = false;
    }
  }, {
    key: 'setExtraData',
    value: function setExtraData(key, value) {
      this.extra[key] = value;
    }
  }, {
    key: 'incExtraDataKey',
    value: function incExtraDataKey(key, value) {
      if (this.extra[key]) {
        this.extra[key] += value || 1;
      } else {
        this.extra[key] = value || 1;
      }
    }
  }, {
    key: 'hashData',
    value: function hashData(data) {
      if (this.anonymous) {
        return (0, (_objectHash || _load_objectHash()).default)(data);
      }
      return data;
    }
  }, {
    key: 'addBreadCrumb',
    value: function addBreadCrumb(category, message, data) {
      this.breadcrumbs.push(new Breadcrumb(category, message, data));
    }
  }, {
    key: 'toObject',
    value: function toObject() {
      return {
        username: this.username,
        command: this.command,
        flags: this.flags,
        args: this.args,
        release: this.release,
        extra: this.extra,
        nodeVersion: this.nodeVersion,
        os: this.os,
        level: this.level,
        error: this.error,
        success: this.success,
        breadcrumbs: this.breadcrumbs,
        analytics_usage: this.analytics_usage,
        error_usage: this.analytics_usage,
        environment: this.environment
      };
    }
  }]);

  return Analytics;
}();

Analytics.flags = {};
Analytics.success = true;
Analytics.extra = {};
Analytics.breadcrumbs = [];


module.exports = { LEVEL, Analytics };