///<reference path="..\Declarations\node\node.d.ts" />
var http = require("http");
var https = require("https");
var Logging = require("../Library/Logging");
var RequestDataHelper = require("./RequestDataHelper");
var AutoCollectRequests = (function () {
    function AutoCollectRequests(client) {
        if (!!AutoCollectRequests.INSTANCE) {
            throw new Error("Request tracking should be configured from the applicationInsights object");
        }
        AutoCollectRequests.INSTANCE = this;
        this._client = client;
    }
    AutoCollectRequests.prototype.enable = function (isEnabled) {
        this._isEnabled = isEnabled;
        if (this._isEnabled && !this._isInitialized) {
            this._initialize();
        }
    };
    AutoCollectRequests.prototype.isInitialized = function () {
        return this._isInitialized;
    };
    AutoCollectRequests.prototype._initialize = function () {
        var _this = this;
        this._isInitialized = true;
        var originalHttpServer = http.createServer;
        http.createServer = function (onRequest) {
            // todo: get a pointer to the server so the IP address can be read from server.address
            return originalHttpServer(function (request, response) {
                if (_this._isEnabled) {
                    AutoCollectRequests.trackRequest(_this._client, request, response);
                }
                if (typeof onRequest === "function") {
                    onRequest(request, response);
                }
            });
        };
        var originalHttpsServer = https.createServer;
        https.createServer = function (options, onRequest) {
            return originalHttpsServer(options, function (request, response) {
                if (_this._isEnabled) {
                    AutoCollectRequests.trackRequest(_this._client, request, response);
                }
                if (typeof onRequest === "function") {
                    onRequest(request, response);
                }
            });
        };
    };
    /**
     * Tracks a request
     */
    AutoCollectRequests.trackRequest = function (client, request, response, properties) {
        if (!request || !response || !client) {
            Logging.info("AutoCollectRequests.trackRequest was called with invalid parameters: ", !request, !response, !client);
            return;
        }
        // store data about the request
        var requestDataHelper = new RequestDataHelper(request);
        // async processing of the telemetry
        var processRequest = function (isError) {
            setTimeout(function () {
                requestDataHelper.onResponse(response, properties);
                var data = requestDataHelper.getRequestData();
                var tags = requestDataHelper.getRequestTags(client.context.tags);
                client.track(data, tags);
            }, 0);
        };
        // response listeners
        if (response && response.once) {
            response.once("finish", function () { return processRequest(); });
        }
        // track a failed request if an error is emitted
        if (request && request.on) {
            request.on("error", function (error) {
                if (!properties) {
                    properties = {};
                }
                if (error) {
                    if (typeof error === "string") {
                        properties["error"] = error;
                    }
                    else if (typeof error === "object") {
                        for (var key in error) {
                            properties[key] = error[key] && error[key].toString && error[key].toString();
                        }
                    }
                }
                processRequest(true);
            });
        }
    };
    AutoCollectRequests.prototype.dispose = function () {
        AutoCollectRequests.INSTANCE = null;
        this._isInitialized = false;
    };
    return AutoCollectRequests;
})();
module.exports = AutoCollectRequests;
