"use strict";
var helpers = require("../helpers");
var Future = require("fibers/future");
global.XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
global.XMLHttpRequest.prototype.withCredentials = false;
var AnalyticsServiceBase = (function () {
    function AnalyticsServiceBase($logger, $options, $staticConfig, $errors, $prompter, $userSettingsService, $analyticsSettingsService, $progressIndicator, $osInfo) {
        this.$logger = $logger;
        this.$options = $options;
        this.$staticConfig = $staticConfig;
        this.$errors = $errors;
        this.$prompter = $prompter;
        this.$userSettingsService = $userSettingsService;
        this.$analyticsSettingsService = $analyticsSettingsService;
        this.$progressIndicator = $progressIndicator;
        this.$osInfo = $osInfo;
        this.analyticsStatuses = {};
        this.isAnalyticsStatusesInitialized = false;
    }
    Object.defineProperty(AnalyticsServiceBase.prototype, "acceptTrackFeatureSetting", {
        get: function () {
            return "Accept" + this.$staticConfig.TRACK_FEATURE_USAGE_SETTING_NAME;
        },
        enumerable: true,
        configurable: true
    });
    AnalyticsServiceBase.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, true).wait();
                    if (!trackFeatureUsage) {
                        _this.setStatus(_this.$staticConfig.ERROR_REPORT_SETTING_NAME, trackFeatureUsage, true).wait();
                    }
                    _this.checkConsentCore(trackFeatureUsage).wait();
                }
                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()();
    };
    AnalyticsServiceBase.prototype.trackFeature = function (featureName) {
        var category = this.$options.analyticsClient ||
            (helpers.isInteractive() ? "CLI" : "Non-interactive");
        return this.track(category, featureName);
    };
    AnalyticsServiceBase.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()();
    };
    AnalyticsServiceBase.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()();
    };
    AnalyticsServiceBase.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()();
    };
    AnalyticsServiceBase.prototype.isEnabled = function (settingName) {
        var _this = this;
        return (function () {
            var analyticsStatus = _this.getStatus(settingName).wait();
            return analyticsStatus === AnalyticsStatus.enabled;
        }).future()();
    };
    AnalyticsServiceBase.prototype.tryStopEqatecMonitor = function (code) {
        if (this._eqatecMonitor) {
            process.removeListener("exit", this.tryStopEqatecMonitor);
            this._eqatecMonitor.stop();
            this._eqatecMonitor = null;
        }
    };
    AnalyticsServiceBase.prototype.getStatusMessage = function (settingName, jsonFormat, readableSettingName) {
        if (jsonFormat) {
            return this.getJsonStatusMessage(settingName);
        }
        return this.getHumanReadableStatusMessage(settingName, readableSettingName);
    };
    AnalyticsServiceBase.prototype.restartEqatecMonitor = function (projectApiKey) {
        var _this = this;
        return (function () {
            _this.tryStopEqatecMonitor();
            _this.start(projectApiKey).wait();
        }).future()();
    };
    AnalyticsServiceBase.prototype.checkConsentCore = function (trackFeatureUsage) {
        return this.trackFeatureCore(this.acceptTrackFeatureSetting + "." + !!trackFeatureUsage);
    };
    AnalyticsServiceBase.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()();
    };
    AnalyticsServiceBase.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()();
    };
    AnalyticsServiceBase.prototype.start = function (analyticsProjectKey) {
        var _this = this;
        return (function () {
            if (_this._eqatecMonitor) {
                return;
            }
            require("../vendor/EqatecMonitor.min");
            analyticsProjectKey = analyticsProjectKey || _this.$staticConfig.ANALYTICS_API_KEY;
            var settings = global._eqatec.createSettings(analyticsProjectKey);
            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(analyticsProjectKey).wait();
                _this.$analyticsSettingsService.setUserSessionsCount(++currentCount, analyticsProjectKey).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()();
    };
    AnalyticsServiceBase.prototype.reportNodeVersion = function () {
        var _this = this;
        return (function () {
            var reportedVersion = process.version.slice(1).replace(/[.]/g, "_");
            _this.track("NodeJSVersion", reportedVersion).wait();
        }).future()();
    };
    AnalyticsServiceBase.prototype.getUserAgentString = function () {
        var userAgentString;
        var osType = this.$osInfo.type();
        if (osType === "Windows_NT") {
            userAgentString = "(Windows NT " + this.$osInfo.release() + ")";
        }
        else if (osType === "Darwin") {
            userAgentString = "(Mac OS X " + this.$osInfo.release() + ")";
        }
        else {
            userAgentString = "(" + osType + ")";
        }
        return userAgentString;
    };
    AnalyticsServiceBase.prototype.isNotConfirmed = function (settingName) {
        var _this = this;
        return (function () {
            var analyticsStatus = _this.getStatus(settingName).wait();
            return analyticsStatus === AnalyticsStatus.notConfirmed;
        }).future()();
    };
    AnalyticsServiceBase.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()();
    };
    AnalyticsServiceBase.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()();
    };
    AnalyticsServiceBase.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()();
    };
    AnalyticsServiceBase.prototype.getIsSending = function () {
        return this._eqatecMonitor.status().isSending;
    };
    AnalyticsServiceBase.prototype.waitForSending = function () {
        var _this = this;
        var future = new Future();
        var intervalTime = 1000;
        var remainingTime = AnalyticsServiceBase.MAX_WAIT_SENDING_INTERVAL;
        if (this.getIsSending()) {
            this.$logger.trace("Waiting for analytics to send information. Will check in a " + intervalTime + "ms.");
            var interval_1 = setInterval(function () {
                if (!_this.getIsSending() || (remainingTime <= 0)) {
                    clearInterval(interval_1);
                    future.return();
                }
                remainingTime -= intervalTime;
                _this.$logger.trace("Waiting for analytics to send information. Will check in a " + intervalTime + "ms. Remaining time is: " + remainingTime);
            }, intervalTime);
        }
        else {
            future.return();
        }
        return future;
    };
    AnalyticsServiceBase.MAX_WAIT_SENDING_INTERVAL = 30000;
    return AnalyticsServiceBase;
}());
exports.AnalyticsServiceBase = AnalyticsServiceBase;
(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;
