"use strict";
var helpers = require("../helpers");
var os = require("os");
var Future = require("fibers/future");
global.XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
global.XMLHttpRequest.prototype.withCredentials = false;
var AnalyticsService = (function () {
    function AnalyticsService($staticConfig, $logger, $errors, $prompter, $userSettingsService, $analyticsSettingsService, $options, $progressIndicator) {
        this.$staticConfig = $staticConfig;
        this.$logger = $logger;
        this.$errors = $errors;
        this.$prompter = $prompter;
        this.$userSettingsService = $userSettingsService;
        this.$analyticsSettingsService = $analyticsSettingsService;
        this.$options = $options;
        this.$progressIndicator = $progressIndicator;
        this.analyticsStatuses = {};
        this.isAnalyticsStatusesInitialized = false;
    }
    Object.defineProperty(AnalyticsService.prototype, "acceptTrackFeatureSetting", {
        get: function () {
            return "Accept" + this.$staticConfig.TRACK_FEATURE_USAGE_SETTING_NAME;
        },
        enumerable: true,
        configurable: true
    });
    AnalyticsService.prototype.checkConsent = function () {
        var _this = this;
        return (function () {
            if (_this.$analyticsSettingsService.canDoRequest().wait()) {
                if (_this.isNotConfirmed(_this.$staticConfig.TRACK_FEATURE_USAGE_SETTING_NAME).wait() && helpers.isInteractive()) {
                    _this.$logger.out("Do you want to help us improve "
                        + _this.$analyticsSettingsService.getClientName()
                        + " by automatically sending anonymous usage statistics? We will not use this information to identify or contact you."
                        + " You can read our official Privacy Policy at");
                    var message = _this.$analyticsSettingsService.getPrivacyPolicyLink();
                    var trackFeatureUsage = _this.$prompter.confirm(message, function () { return true; }).wait();
                    _this.setStatus(_this.$staticConfig.TRACK_FEATURE_USAGE_SETTING_NAME, trackFeatureUsage, false).wait();
                    if (!trackFeatureUsage) {
                        _this.setStatus(_this.$staticConfig.ERROR_REPORT_SETTING_NAME, trackFeatureUsage, false).wait();
                    }
                    _this.restartEqatecMonitor(_this.$staticConfig.ANALYTICS_FEATURE_USAGE_TRACKING_API_KEY).wait();
                    _this.trackFeatureCore(_this.acceptTrackFeatureSetting + "." + !!trackFeatureUsage).wait();
                    _this.tryStopEqatecMonitor();
                }
                if (_this.isNotConfirmed(_this.$staticConfig.ERROR_REPORT_SETTING_NAME).wait()) {
                    _this.$logger.out("Error reporting will be enabled. You can disable it by running '$ " + _this.$staticConfig.CLIENT_NAME.toLowerCase() + " error-reporting disable'.");
                    _this.setStatus(_this.$staticConfig.ERROR_REPORT_SETTING_NAME, true).wait();
                }
            }
        }).future()();
    };
    AnalyticsService.prototype.trackFeature = function (featureName) {
        var category = this.$options.analyticsClient ||
            (helpers.isInteractive() ? "CLI" : "Non-interactive");
        return this.track(category, featureName);
    };
    AnalyticsService.prototype.track = function (featureName, featureValue) {
        var _this = this;
        return (function () {
            _this.initAnalyticsStatuses().wait();
            _this.$logger.trace("Trying to track feature '" + featureName + "' with value '" + featureValue + "'.");
            if (_this.analyticsStatuses[_this.$staticConfig.TRACK_FEATURE_USAGE_SETTING_NAME] === AnalyticsStatus.enabled) {
                _this.trackFeatureCore(featureName + "." + featureValue).wait();
            }
        }).future()();
    };
    AnalyticsService.prototype.trackFeatureCore = function (featureTrackString) {
        var _this = this;
        return (function () {
            try {
                if (_this.$analyticsSettingsService.canDoRequest().wait()) {
                    _this.start().wait();
                    if (_this._eqatecMonitor) {
                        _this._eqatecMonitor.trackFeature(featureTrackString);
                        _this.waitForSending().wait();
                    }
                }
            }
            catch (e) {
                _this.$logger.trace("Analytics exception: '%s'", e.toString());
            }
        }).future()();
    };
    AnalyticsService.prototype.trackException = function (exception, message) {
        var _this = this;
        return (function () {
            _this.initAnalyticsStatuses().wait();
            _this.$logger.trace("Trying to track exception with message '" + message + "'.");
            if (_this.analyticsStatuses[_this.$staticConfig.ERROR_REPORT_SETTING_NAME] === AnalyticsStatus.enabled
                && _this.$analyticsSettingsService.canDoRequest().wait()) {
                try {
                    _this.start().wait();
                    if (_this._eqatecMonitor) {
                        _this.$logger.printInfoMessageOnSameLine("Sending exception report (press Ctrl+C to stop)...");
                        _this._eqatecMonitor.trackException(exception, message);
                        _this.$progressIndicator.showProgressIndicator(_this.waitForSending(), 500).wait();
                    }
                }
                catch (e) {
                    _this.$logger.trace("Analytics exception: '%s'", e.toString());
                }
            }
        }).future()();
    };
    AnalyticsService.prototype.setStatus = function (settingName, enabled, doNotTrackSetting) {
        var _this = this;
        return (function () {
            _this.analyticsStatuses[settingName] = enabled ? AnalyticsStatus.enabled : AnalyticsStatus.disabled;
            _this.$userSettingsService.saveSetting(settingName, enabled.toString()).wait();
            if (!doNotTrackSetting) {
                _this.trackFeatureCore(settingName + "." + (enabled ? "enabled" : "disabled")).wait();
            }
            if (_this.analyticsStatuses[settingName] === AnalyticsStatus.disabled
                && _this.analyticsStatuses[settingName] === AnalyticsStatus.disabled) {
                _this.tryStopEqatecMonitor();
            }
        }).future()();
    };
    AnalyticsService.prototype.getStatus = function (settingName) {
        var _this = this;
        return (function () {
            if (!_this.analyticsStatuses[settingName]) {
                var settingValue = _this.$userSettingsService.getSettingValue(settingName).wait();
                if (settingValue) {
                    var isEnabled = helpers.toBoolean(settingValue);
                    if (isEnabled) {
                        _this.analyticsStatuses[settingName] = AnalyticsStatus.enabled;
                    }
                    else {
                        _this.analyticsStatuses[settingName] = AnalyticsStatus.disabled;
                    }
                }
                else {
                    _this.analyticsStatuses[settingName] = AnalyticsStatus.notConfirmed;
                }
            }
            return _this.analyticsStatuses[settingName];
        }).future()();
    };
    AnalyticsService.prototype.start = function (analyticsProjectKey) {
        var _this = this;
        return (function () {
            if (_this._eqatecMonitor) {
                return;
            }
            require("../vendor/EqatecMonitor.min");
            var settings = global._eqatec.createSettings(analyticsProjectKey || _this.$staticConfig.ANALYTICS_API_KEY);
            settings.useHttps = false;
            settings.userAgent = _this.getUserAgentString();
            settings.version = _this.$staticConfig.version;
            settings.useCookies = false;
            settings.loggingInterface = {
                logMessage: _this.$logger.trace.bind(_this.$logger),
                logError: _this.$logger.debug.bind(_this.$logger)
            };
            _this._eqatecMonitor = global._eqatec.createMonitor(settings);
            var guid = _this.$userSettingsService.getSettingValue(_this.$staticConfig.ANALYTICS_INSTALLATION_ID_SETTING_NAME).wait();
            if (!guid) {
                guid = helpers.createGUID(false);
                _this.$userSettingsService.saveSetting(_this.$staticConfig.ANALYTICS_INSTALLATION_ID_SETTING_NAME, guid).wait();
            }
            _this.$logger.trace("%s: %s", _this.$staticConfig.ANALYTICS_INSTALLATION_ID_SETTING_NAME, guid.toString());
            _this._eqatecMonitor.setInstallationID(guid);
            try {
                _this._eqatecMonitor.setUserID(_this.$analyticsSettingsService.getUserId().wait());
                var currentCount = _this.$analyticsSettingsService.getUserSessionsCount().wait();
                _this.$analyticsSettingsService.setUserSessionsCount(++currentCount).wait();
                _this._eqatecMonitor.setStartCount(currentCount);
            }
            catch (e) {
                _this.$logger.trace("Error while initializing eqatecMonitor", e);
            }
            _this._eqatecMonitor.start();
            process.on("exit", _this.tryStopEqatecMonitor);
            _this.reportNodeVersion().wait();
        }).future()();
    };
    AnalyticsService.prototype.reportNodeVersion = function () {
        var _this = this;
        return (function () {
            var reportedVersion = process.version.slice(1).replace(/[.]/g, "_");
            _this.track("NodeJSVersion", reportedVersion).wait();
        }).future()();
    };
    AnalyticsService.prototype.getUserAgentString = function () {
        var userAgentString;
        var osType = os.type();
        if (osType === "Windows_NT") {
            userAgentString = "(Windows NT " + os.release() + ")";
        }
        else if (osType === "Darwin") {
            userAgentString = "(Mac OS X " + os.release() + ")";
        }
        else {
            userAgentString = "(" + osType + ")";
        }
        return userAgentString;
    };
    AnalyticsService.prototype.isEnabled = function (settingName) {
        var _this = this;
        return (function () {
            var analyticsStatus = _this.getStatus(settingName).wait();
            return analyticsStatus === AnalyticsStatus.enabled;
        }).future()();
    };
    AnalyticsService.prototype.tryStopEqatecMonitor = function (code) {
        if (this._eqatecMonitor) {
            process.removeListener("exit", this.tryStopEqatecMonitor);
            this._eqatecMonitor.stop();
            this._eqatecMonitor = null;
        }
    };
    AnalyticsService.prototype.isNotConfirmed = function (settingName) {
        var _this = this;
        return (function () {
            var analyticsStatus = _this.getStatus(settingName).wait();
            return analyticsStatus === AnalyticsStatus.notConfirmed;
        }).future()();
    };
    AnalyticsService.prototype.getStatusMessage = function (settingName, jsonFormat, readableSettingName) {
        if (jsonFormat) {
            return this.getJsonStatusMessage(settingName);
        }
        return this.getHumanReadableStatusMessage(settingName, readableSettingName);
    };
    AnalyticsService.prototype.getHumanReadableStatusMessage = function (settingName, readableSettingName) {
        var _this = this;
        return (function () {
            var status = null;
            if (_this.isNotConfirmed(settingName).wait()) {
                status = "disabled until confirmed";
            }
            else {
                status = AnalyticsStatus[_this.getStatus(settingName).wait()];
            }
            return readableSettingName + " is " + status + ".";
        }).future()();
    };
    AnalyticsService.prototype.getJsonStatusMessage = function (settingName) {
        var _this = this;
        return (function () {
            var status = _this.getStatus(settingName).wait();
            var enabled = status === AnalyticsStatus.notConfirmed ? null : status === AnalyticsStatus.disabled ? false : true;
            return JSON.stringify({ enabled: enabled });
        }).future()();
    };
    AnalyticsService.prototype.initAnalyticsStatuses = function () {
        var _this = this;
        return (function () {
            if (_this.$analyticsSettingsService.canDoRequest().wait()) {
                if (!_this.isAnalyticsStatusesInitialized) {
                    _this.$logger.trace("Initializing analytics statuses.");
                    var settingsNames = [_this.$staticConfig.TRACK_FEATURE_USAGE_SETTING_NAME, _this.$staticConfig.ERROR_REPORT_SETTING_NAME];
                    settingsNames.forEach(function (settingName) { return _this.getStatus(settingName).wait(); });
                    _this.isAnalyticsStatusesInitialized = true;
                }
                _this.$logger.trace("Analytics statuses: ");
                _this.$logger.trace(_this.analyticsStatuses);
            }
        }).future()();
    };
    AnalyticsService.prototype.getIsSending = function () {
        return this._eqatecMonitor.status().isSending;
    };
    AnalyticsService.prototype.waitForSending = function () {
        var _this = this;
        var future = new Future();
        var intervalTime = 1000;
        var remainingTime = AnalyticsService.MAX_WAIT_SENDING_INTERVAL;
        var interval = setInterval(function () {
            if (!_this.getIsSending() || (remainingTime <= 0)) {
                clearInterval(interval);
                future.return();
            }
            remainingTime -= intervalTime;
        }, intervalTime);
        return future;
    };
    AnalyticsService.prototype.restartEqatecMonitor = function (projectApiKey) {
        var _this = this;
        return (function () {
            _this.tryStopEqatecMonitor();
            _this.start(projectApiKey).wait();
        }).future()();
    };
    AnalyticsService.MAX_WAIT_SENDING_INTERVAL = 30000;
    return AnalyticsService;
})();
exports.AnalyticsService = AnalyticsService;
$injector.register("analyticsService", AnalyticsService);
(function (AnalyticsStatus) {
    AnalyticsStatus[AnalyticsStatus["enabled"] = 0] = "enabled";
    AnalyticsStatus[AnalyticsStatus["disabled"] = 1] = "disabled";
    AnalyticsStatus[AnalyticsStatus["notConfirmed"] = 2] = "notConfirmed";
})(exports.AnalyticsStatus || (exports.AnalyticsStatus = {}));
var AnalyticsStatus = exports.AnalyticsStatus;
