const tls = require('tls');
const net = require('net');

const SMTP_HOST = 'mail.fichtmueller.org';
const SMTP_PORT = 587;
const MAIL_TO   = 'peercortex@context-x.org';
const MAIL_FROM = 'PeerCortex Feedback <rene@fichtmueller.org>';

function sendFeedbackMail(entry) {
  const SMTP_USER = process.env.SMTP_USER;
  const SMTP_PASS = process.env.SMTP_PASS;

  return new Promise(function(resolve, reject) {
    var b64 = function(s) { return Buffer.from(s).toString('base64'); };
    var CRLF = '\r\n';
    var body = 'Category : ' + entry.category + CRLF +
      'Name     : ' + entry.name + CRLF +
      'ASN      : ' + (entry.asn || '-') + CRLF +
      'Time     : ' + entry.timestamp + CRLF + CRLF +
      entry.message + CRLF + CRLF + '-' + CRLF + 'PeerCortex Feedback';
    var subj = '[PeerCortex Feedback] ' + entry.category + (entry.asn ? ' - AS' + entry.asn : '');
    var msg = 'From: ' + MAIL_FROM + CRLF +
      'To: ' + MAIL_TO + CRLF +
      'Subject: ' + subj + CRLF +
      'MIME-Version: 1.0' + CRLF +
      'Content-Type: text/plain; charset=UTF-8' + CRLF + CRLF +
      body;

    var socket = net.connect(SMTP_PORT, SMTP_HOST);
    var tlsSocket = null;
    var buf = '';
    var step = 0;
    var done = false;

    function send(line) {
      var s = tlsSocket || socket;
      s.write(line + CRLF);
    }

    function onData(data) {
      buf += data.toString();
      var lines = buf.split(CRLF);
      buf = lines.pop();
      for (var i = 0; i < lines.length; i++) {
        var line = lines[i];
        var code = parseInt(line.slice(0, 3));
        if (isNaN(code) || line[3] === '-') continue;
        if (step === 0 && code === 220) { send('EHLO peercortex.org'); step = 1; }
        else if (step === 1 && code === 250) { send('STARTTLS'); step = 2; }
        else if (step === 2 && code === 220) {
          tlsSocket = tls.connect({ socket: socket, servername: SMTP_HOST, rejectUnauthorized: false }, function() {
            tlsSocket.on('data', onData);
            send('EHLO peercortex.org');
            step = 3;
          });
          tlsSocket.on('error', function(e) { if (!done) { done = true; reject(e); } });
        }
        else if (step === 3 && code === 250) { send('AUTH LOGIN'); step = 4; }
        else if (step === 4 && code === 334) { send(b64(SMTP_USER)); step = 5; }
        else if (step === 5 && code === 334) { send(b64(SMTP_PASS)); step = 6; }
        else if (step === 6 && code === 235) { send('MAIL FROM:<' + SMTP_USER + '>'); step = 7; }
        else if (step === 7 && code === 250) { send('RCPT TO:<' + MAIL_TO + '>'); step = 8; }
        else if (step === 8 && code === 250) { send('DATA'); step = 9; }
        else if (step === 9 && code === 354) { send(msg + CRLF + '.'); step = 10; }
        else if (step === 10 && code === 250) { send('QUIT'); if (!done) { done = true; resolve(); } }
        else if (code >= 400) { if (!done) { done = true; reject(new Error('SMTP ' + code + ': ' + line)); } }
      }
    }

    socket.on('data', onData);
    socket.on('error', function(e) { if (!done) { done = true; reject(e); } });
    setTimeout(function() { if (!done) { done = true; reject(new Error('SMTP timeout')); } }, 15000);
  });
}

module.exports = {
  sendFeedbackMail
};
