/**************************************************************************************************
 *
 * ADOBE SYSTEMS INCORPORATED
 * Copyright 2015 Adobe Systems Incorporated
 * All Rights Reserved.
 *
 * NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the
 * terms of the Adobe license agreement accompanying it.  If you have received this file from a
 * source other than Adobe, then your use, modification, or distribution of it requires the prior
 * written permission of Adobe.
 *
 **************************************************************************************************/

/*jslint vars: true, node: true, plusplus: true, unparam: true, nomen: true, regexp: true */

//Loosely based on node-tunnel(https://github.com/koichik/node-tunnel.git)
//Better implementation(needs to be converted to Async):https://github.com/nodejs/node/blob/master/lib/_http_agent.js
'use strict';

var http = require('http');
var https = require('https');
var util = require('util');
var ProxyConnection = require('./proxyConnection');

function createConnection(options, callback) {
    var self = this;
    options = Object.assign({}, self.options, options || {});
    options.proxy = options.proxy || {};
    options.proxy.authenticate = exports.agent.authenticate;
    var connection = new ProxyConnection.Connection(options);
    connection.on('success', function () {
        callback(null, connection.socket);
    });

    connection.on('error', function (error) {
        callback(new Error(error));
    });
}

function createSecureConnection(options, callback) {
    options = options || {};
    var self = this, tlsSocket;
    var superCreateConnection = https.Agent.prototype.createConnection;

    //Create a session
    createConnection.call(this, options, function (err, socket) {
        if (err) {
            callback(err);
        } else {
            options.socket = socket;
            tlsSocket = superCreateConnection.call(self, options);
            callback(null, tlsSocket);
        }
    });
}

function HTTPAgent(options) {
    http.Agent.apply(this, arguments);
}

util.inherits(HTTPAgent, http.Agent);
HTTPAgent.prototype.createConnection = createConnection;

function HTTPSAgent(options) {
    https.Agent.apply(this, arguments);
}

util.inherits(HTTPSAgent, https.Agent);
HTTPSAgent.prototype.createConnection = createSecureConnection;

exports.agent = function getTunnelingAgent(options) {
    options = options || {};
    if (options.insecure) {
        return new HTTPAgent(options);
    }
    return new HTTPSAgent(options);

};

exports.HTTPAgent = HTTPAgent;
exports.HTTPSAgent = HTTPSAgent;

exports.agent.authenticate = function (options, callback) {
    callback('No Credentials supplied');
};

exports.init = function (getNegotiateTokenFn) {
    ProxyConnection.init(getNegotiateTokenFn);
};
