/**
 * smtp-email.js
 * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
 *
 * Contact:
 * Sungmin Kim <sm.art.kim@samsung.com>
 * Jonghwan Park <iwin100.park@samsung.com>
 * Kitae Kim <kt920.kim@samsung.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Contributors:
 * - S-Core Co., Ltd
**/

var dibs = require('../../core/dibs');
var DError = require('../../core/exception.js');
var nodemailer = require('nodemailer');
var path = require('path');
var fs = require('fs');
var yaml = require('js-yaml');
var _ = require('underscore');

module.exports.create = create;
module.exports.notify = notify;
module.exports.close = close;

var CONFIG_FILE = 'smtp-email.yaml';
var adminEmail = 'admin@dibs.com';
var excludeEmailList = [];
var smtpTransportObj;

function create(configDir) {
    // get config
    var config = getConfig(path.join(configDir, CONFIG_FILE));

    if (config) {
        // set info
        var host = config.get('SMTP_host');
        var port = config.get('SMTP_port');
        var user = config.get('SMTP_authentication_user');
        var pass = config.get('SMTP_authentication_pass');
        var admin = config.get('SMTP_admin_email');
        var excludeList = config.get('Exclude_Email_List');

        // exclude list check
        if (excludeList && _.isArray(excludeList)) {
            excludeEmailList = excludeList;
        }

        // smtp enable check
        if (host) {
            // default port/admin-email setting
            if (!port) {
                port = 25;
            }
            if (admin) {
                adminEmail = admin;
            }

            // smtp authentication option check
            if (user && pass) {
                smtpTransportObj = nodemailer.createTransport('SMTP', {
                    host: host,
                    port: port,
                    auth: {
                        user: user,
                        pass: pass
                    }
                });
            } else {
                smtpTransportObj = nodemailer.createTransport({
                    host: host,
                    port: port
                }, {
                    from: adminEmail,
                    headers: {
                        'X-Laziness-level': 1000
                    }
                });
            }
        }
    } else {
        smtpTransportObj = null;
    }
}

function close() {
    if (smtpTransportObj) {
        smtpTransportObj.close();
    }
}

function notify(subject, target, message, callback) {
    // convert target email list
    var convertedInput;
    if (target && _.isArray(target) && target.length !== 0) {
        convertedInput = target;
    } else if (target && !_.isArray(target) && target !== '') {
        // string -> array
        convertedInput = target.split(',');
    } else {
        return callback(new Error('target email is empty'));
    }
    dibs.log.info('Input email list ' + target.toString());

    // exclude list
    var targetList = _.difference(convertedInput, excludeEmailList);
    if (targetList.length === 0) {
        // there is no target
        return callback(null);
    }
    dibs.log.info('Sending email to ' + targetList.toString());

    // generate message object
    if (smtpTransportObj) {
        var msgObj = {
            to: targetList,
            subject: subject,
            text: message +
                '\n\n' +
                '===========================================================\n' +
                '= This is an "outgoing only" mail. Please do not respond. =\n' +
                '===========================================================\n'
        };
        // send mail
        smtpTransportObj.sendMail(msgObj, function (err, info) {
            if (err) {
                dibs.log.error(err);
            }
            dibs.log.info(info);
            callback(err);
        });
    } else {
        return callback(new DError('MESSENGER001'));
    }

}

function getConfig(path) {
    if (fs.existsSync(path)) {
        return loadConfig(path);
    } else {
        return null;
    }
}

function loadConfig(path) {
    var config = new PluginConfig();
    var readConfig = yaml.safeLoad(fs.readFileSync(path, 'utf-8'));

    for (var key in readConfig) {
        config.set(key, readConfig[key]);
    }

    return config;
}

function PluginConfig() {
    var config = {};

    this.set = function (key, val) {
        config[key] = val;
        return;
    };

    this.get = function (key) {
        return config[key];
    };

    this.toString = function () {
        return yaml.dump(config);
    };

    this.getConfigData = function () {
        return config;
    };
}
