var MemBuffer = require('./MemBuffer');
var AsyncMemBuffer = require('./AsyncMemBuffer');
var net = require('net');

global.namedPipeQueue = global.namedPipeQueue || [];

function NamedPipeTransport (pipename) {
    this.pipename = pipename;
    this.input = new MemBuffer();
    this.queue = global.namedPipeQueue;
};

NamedPipeTransport.prototype.open = function () {
};

NamedPipeTransport.prototype.close = function () {
};

NamedPipeTransport.prototype.read = function (len) {
    throw Error('NamedPipeTransport object does not support reads');
};

NamedPipeTransport.prototype.write = function (bytes) {
    this.input.write(bytes);
};

NamedPipeTransport.prototype.clear = function () {
    this.input.clear();
};

NamedPipeTransport.prototype.flush = function (callback) {
    this.input.flush();
    var request = {
        callback: callback,
        buffer: this.input.buffer
    };
    this.queue.push(request);
    this.clear();

    if (this.queue.length == 1) this.send(request.buffer, callback);
};

NamedPipeTransport.prototype.send = function send(buffer, callback) {
    var me = this;
    var socket = net.connect(this.pipename);
    var response = new AsyncMemBuffer();
    var firstByteReceived = false;

    if (!send.start) send.start = Date.now();

    socket.on('connect', function (err) {
        if (err) return console.log(err);
        socket.write(buffer);
        send.start = null;
    });

    socket.on('data', function (chunk) {
        response.write(chunk);
        response.flush();

        if (!firstByteReceived) {
            firstByteReceived = true;
            send.start = null;
            response.on('readMessageEnd', function () {
                response = null;
                socket.destroy();
                send.start = null;
                me.next();
            });
            if (callback) callback(null, response);
        }
    });

    socket.on('error', function (err) {
        if (Date.now() - send.start < 3000) {
            console.log('Retrying request at ' + Date.now());
            setImmediate(me.send.bind(me, buffer, callback));
        } else {
            console.log('Problem with request in NamedPipeTransport: ' + err.message);
            if (callback) callback(err);
            send.start = null;
            me.next();
        }
    });
};

NamedPipeTransport.prototype.next = function () {
    var request;
    var me = this;
    this.queue.shift();
    if (this.queue.length > 0) {
        request = this.queue[0];
        setImmediate(me.send.bind(me, request.buffer, request.callback));
    }
};

module.exports = NamedPipeTransport;

