/* this Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

const
emailer = require('nodemailer'),
fs = require('fs'),
path = require('path'),
ejs = require('ejs'),
config = require('./configuration.js'),
logger = require('./logging.js').logger,
url = require('url');

/* if smtp parameters are configured, use them */
try { var smtp_params = config.get('smtp'); } catch(e) {};
if (smtp_params && smtp_params.host) {
  emailer.SMTP = {
    host: smtp_params.host,
    port: smtp_params.port
  };
  logger.info("delivering email via SMTP host: " +  emailer.SMTP.host);
  if (smtp_params.user) {
    emailer.SMTP.use_authentication = true;
    emailer.SMTP.user = smtp_params.user;
    emailer.SMTP.pass = smtp_params.pass;

    logger.info("authenticating to email host as " +  emailer.SMTP.user);
  }
}

const TEMPLATE_PATH = path.join(__dirname, "..", "resources", "email_templates");

// the underbar decorator to allow getext to extract strings
function _(str) { return str; }

// a map of all the different emails we send
const templates = {
  "new": {
    landing: 'verify_email_address',
    subject: _("Confirm email address for Persona"),
    template: fs.readFileSync(path.join(TEMPLATE_PATH, 'new.ejs')),
    templateHTML: fs.readFileSync(path.join(TEMPLATE_PATH, 'new.html.ejs'))
  },
  "reset": {
    landing: 'reset_password',
    subject: _("Reset Persona password"),
    template: fs.readFileSync(path.join(TEMPLATE_PATH, 'reset.ejs')),
    templateHTML: fs.readFileSync(path.join(TEMPLATE_PATH, 'reset.html.ejs'))
  },
  "confirm": {
    landing: 'confirm',
    subject: _("Confirm email address for Persona"),
    template: fs.readFileSync(path.join(TEMPLATE_PATH, 'confirm.ejs')),
    templateHTML: fs.readFileSync(path.join(TEMPLATE_PATH, 'confirm.html.ejs'))
  }
};

// now turn file contents into compiled templates
Object.keys(templates).forEach(function(type) {
  templates[type].template = ejs.compile(templates[type].template.toString());
  if (templates[type].templateHTML) {
    templates[type].templateHTML = ejs.compile(templates[type].templateHTML.toString());
  }
});


var interceptor = undefined;

/**
 * allow clients to intercept email messages programatically for local
 * testing. The `interceptor` is a function which accepts three arguments,
 *
 *   * `email` - the email that is being verified
 *   * `site` - the RP
 *   * `secret` - the verification secret (usually embedded into a url)
 *
 * Limitations: only a single interceptor may be set, generalize
 * as needed.
 */
exports.setInterceptor = function(callback) {
  interceptor = callback;
};

//TODO send in localeContext
function doSend(email_type, email, site, secret, langContext) {
  if (!templates[email_type]) throw "unknown email type: " + email_type;

  // remove scheme from site to make it more human
  site = url.parse(site).hostname;

  var email_params = templates[email_type];

  var public_url = config.get('public_url') + "/" + email_params.landing + "?token=" + encodeURIComponent(secret),
      GETTEXT = langContext.gettext,
      format = langContext.format;

  if (interceptor) {
    interceptor(email, site, secret);
  } else if (config.get('email_to_console')) {
    // log verification email to console separated by whitespace.
    console.log("\nVERIFICATION URL:\n" + public_url + "\n");
  } else {
    var templateArgs = {
      link: public_url,
      site: site,
      gettext: GETTEXT,
      format: format
    };

    var mailOpts = {
      // XXX: Ideally this would be a live email address and a response to these email
      // addresses would go into a ticketing system (lloyd/skinny)
      sender: "Persona <no-reply@persona.org>",
      to: email,
      subject: GETTEXT(email_params.subject),
      text: email_params.template(templateArgs),
      headers: {
        'X-BrowserID-VerificationURL': public_url,
        'X-BrowserID-RelyingParty': site
      }
    };

    if (email_params.templateHTML) {
      mailOpts.html = email_params.templateHTML(templateArgs);
    }

    emailer.send_mail(mailOpts, function(err, success) {
      if (!success) {
        logger.error("error sending email to: " + email + " - " + err);
      }
    });
  };
};

exports.sendNewUserEmail = function(email, site, secret, langContext) {
  doSend('new', email, site, secret, langContext);
};

exports.sendConfirmationEmail = function(email, site, secret, langContext) {
  doSend('confirm', email, site, secret, langContext);
};

exports.sendForgotPasswordEmail = function(email, site, secret, langContext) {
  doSend('reset', email, site, secret, langContext);
};