"use strict";

var createSMTPServer = require("./server"),
    Stream = require("stream").Stream,
    utillib = require("util"),
    oslib = require("os");

module.exports = function(options, connectionCallback){
    return new SimpleServer(options, connectionCallback);
};

function SimpleServer(options, connectionCallback){
    if(!connectionCallback && typeof options == "function"){
        connectionCallback = options;
        options = undefined;
    }

    this.connectionCallback = connectionCallback;

    this.options = options || {};
    this.initialChunk = true;

    if(!("ignoreTLS" in this.options)){
        this.options.ignoreTLS = true;
    }

    if(!("disableDNSValidation" in this.options)){
        this.options.disableDNSValidation = true;
    }

    this.server = createSMTPServer(options);
    this.listen = this.server.listen.bind(this.server);

    this.server.on("startData", this._onStartData.bind(this));
    this.server.on("data", this._onData.bind(this));
    this.server.on("dataReady", this._onDataReady.bind(this));
}

SimpleServer.prototype._onStartData = function(connection){
    connection._session = new SimpleServerConnection(connection);
    this.connectionCallback(connection._session);
};

SimpleServer.prototype._onData = function(connection, chunk){
    if(this.initialChunk){
        chunk = Buffer.concat([new Buffer(this._generateReceivedHeader(connection) + "\r\n", "utf-8"), chunk]);
        this.initialChunk = false;
    }
    connection._session.emit("data", chunk);
};

SimpleServer.prototype._onDataReady = function(connection, callback){
    connection._session._setCallback(callback);
    connection._session.emit("end");
};

SimpleServer.prototype._generateReceivedHeader = function(connection){
    var parts = [];

    if(connection.host && !connection.host.match(/^\[?\d+\.\d+\.\d+\.\d+\]?$/)){
        parts.push("from " + connection.host);
        parts.push("("+connection.remoteAddress+")");
    }else{
        parts.push("from " + connection.remoteAddress);
    }

    parts.push("by " + getHostName());

    parts.push("with SMTP;");

    parts.push(Date());

    return "Received: " + parts.join(" ");
};

function SimpleServerConnection(connection){
    Stream.call(this);

    this.accepted = false;
    this.rejected = false;

    this._callback = (function(err, code){
        if(err){
            this.rejected = err;
        }else{
            this.accepted = code || true;
        }
    });

    ["from", "to", "host", "remoteAddress"].forEach((function(key){
        if(connection[key]){
            this[key] = connection[key];
        }
    }).bind(this));
}
utillib.inherits(SimpleServerConnection, Stream);

SimpleServerConnection.prototype._setCallback = function(callback){

    if(this.rejected){
        return callback(this.rejected);
    }else if(this.accepted){
        return callback(null, this.accepted !== true ? this.accepted : undefined);
    }else{
        this._callback = callback;
    }

};

SimpleServerConnection.prototype.pause = function(){};

SimpleServerConnection.prototype.resume = function(){};

SimpleServerConnection.prototype.accept = function(code){
    this._callback(null, code);
};

SimpleServerConnection.prototype.reject = function(reason){
    this._callback(new Error(reason || "Rejected"));
};

function getHostName(){
    return (oslib.hostname && oslib.hostname()) ||
          (oslib.getHostname && oslib.getHostname()) ||
          "127.0.0.1";
}
