/*******************************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 *******************************************************************************/
package org.ofbiz.common.email;

import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.net.InetAddress;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.Locale;
import java.util.Map;

import javolution.util.FastMap;

import org.ofbiz.base.container.ClassLoaderContainer;
import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.UtilGenerics;
import org.ofbiz.base.util.UtilMisc;
import org.ofbiz.base.util.UtilProperties;
import org.ofbiz.base.util.UtilURL;
import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.base.util.template.FreeMarkerWorker;
import org.ofbiz.entity.Delegator;
import org.ofbiz.entity.GenericEntityException;
import org.ofbiz.entity.GenericValue;
import org.ofbiz.entity.util.EntityUtilProperties;
import org.ofbiz.service.DispatchContext;
import org.ofbiz.service.GenericServiceException;
import org.ofbiz.service.LocalDispatcher;
import org.ofbiz.service.ModelService;
import org.ofbiz.service.ServiceUtil;

import freemarker.template.TemplateException;

/**
 * Provides generic services related to preparing and
 * delivering notifications via email.
 * <p>
 * To use the NotificationService, a message specific service should be
 * defined for a particular <a href="http://freemarker.sourceforge.net/docs/dgui_quickstart_template.html">
 * Freemarker Template</a> mapping the required fields of the
 * template to the required attributes of the service.
 * <p>
 * This service definition should extend the <code>sendNotificationInterface<code>
 * or the <code>prepareNotificationInterface</code> service interface
 * and simply invoke the associated method defined in this class.
 * <p>
 * <blockquote>
 * <pre>
 *     &lt;service name="sendPoPickupNotification" engine="java"
 *             location="org.ofbiz.content.email.NotificationServices" invoke="sendNotification"&gt;
 *         &lt;description&gt;Sends notification based on a message template&lt;/description&gt;
 *         &lt;implements service="sendNotificationInterface"/&gt;
 *         &lt;attribute name="orderId" type="String" mode="IN" optional="false"/&gt;
 *     &lt;/service&gt;
 * </pre>
 * </blockquote>
 * <p>
 * An optional parameter available to all message templates is <code>baseUrl</code>
 * which can either be specified when the service is invoked or let the
 * <code>NotificationService</code> attempt to resolve it as best it can,
 * see {@link #setBaseUrl(Delegator, String, Map) setBaseUrl(Map)} for details on how this is achieved.
 * <p>
 * The following example shows what a simple notification message template,
 * associated with the above service, might contain:
 * <blockquote>
 * <pre>
 *     Please use the following link to schedule a delivery date:
 *     &lt;p&gt;
 *     ${baseUrl}/ordermgr/control/schedulepo?orderId=${orderId}"
 * </pre>
 * </blockquote>
 * <p>
 * The template file must be found on the classpath at runtime and
 * match the "templateName" field passed to the service when it
 * is invoked.
 * <p>
 * For complex messages with a large number of dynamic fields, it may be wise
 * to implement a custom service that takes one or two parameters that can
 * be used to resolve the rest of the required fields and then pass them to
 * the {@link #prepareNotification(DispatchContext, Map) prepareNotification(DispatchContext, Map)}
 * or {@link #sendNotification(DispatchContext, Map) sendNotification(DispatchContext, Map)}
 * methods directly to generate or generate and send the notification respectively.
 *
 */
public class NotificationServices {

    public static final String module = NotificationServices.class.getName();
    public static final String resource = "CommonUiLabels";

    /**
     * This will use the {@link #prepareNotification(DispatchContext, Map) prepareNotification(DispatchContext, Map)}
     * method to generate the body of the notification message to send
     * and then deliver it via the "sendMail" service.
     * <p>
     * If the "body" parameter is already specified, the message body generation
     * phase will be skipped and the notification will be sent with the
     * specified body instead. This can be used to combine both service
     * calls in a decoupled manner if other steps are required between
     * generating the message body and sending the notification.
     *
     * @param ctx   The dispatching context of the service
     * @param context The map containing all the fields associated with
     * the sevice
     * @return A Map with the service response messages in it
     */
    public static Map<String, Object> sendNotification(DispatchContext ctx, Map<String, ? extends Object> context) {
        LocalDispatcher dispatcher = ctx.getDispatcher();
        Locale locale = (Locale) context.get("locale");
        Map<String, Object> result = null;

        try {
            // see whether the optional 'body' attribute was specified or needs to be processed
            // nulls are handled the same as not specified
            String body = (String) context.get("body");

            if (body == null) {
                // prepare the body of the notification email
                Map<String, Object> bodyResult = prepareNotification(ctx, context);

                // ensure the body was generated successfully
                if (bodyResult.get(ModelService.RESPONSE_MESSAGE).equals(ModelService.RESPOND_SUCCESS)) {
                    body = (String) bodyResult.get("body");
                } else {
                    // otherwise just report the error
                    Debug.logError("prepareNotification failed: " + bodyResult.get(ModelService.ERROR_MESSAGE), module);
                    body = null;
                }
            }

            // make sure we have a valid body before sending
            if (body != null) {
                // retain only the required attributes for the sendMail service
                Map<String, Object> emailContext = FastMap.newInstance();
                emailContext.put("sendTo", context.get("sendTo"));
                emailContext.put("body", body);
                emailContext.put("sendCc", context.get("sendCc"));
                emailContext.put("sendBcc", context.get("sendBcc"));
                emailContext.put("sendFrom", context.get("sendFrom"));
                emailContext.put("subject", context.get("subject"));
                emailContext.put("sendVia", context.get("sendVia"));
                emailContext.put("sendType", context.get("sendType"));
                emailContext.put("contentType", context.get("contentType"));

                // pass on to the sendMail service
                result = dispatcher.runSync("sendMail", emailContext);
            } else {
                Debug.logError("Invalid email body; null is not allowed", module);
                result = ServiceUtil.returnError(UtilProperties.getMessage(resource, "CommonNotifyEmailInvalidBody", locale));
            }
        } catch (GenericServiceException serviceException) {
            Debug.logError(serviceException, "Error sending email", module);
            result = ServiceUtil.returnError(UtilProperties.getMessage(resource, "CommonNotifyEmailDeliveryError", locale));
        }

        return result;
    }

    /**
     * This will process the associated notification template definition
     * with all the fields contained in the given context and generate
     * the message body of the notification.
     * <p>
     * The result returned will contain the appropriate response
     * messages indicating success or failure and the OUT parameter,
     * "body" containing the generated message.
     *
     * @param ctx   The dispatching context of the service
     * @param context The map containing all the fields associated with
     * the sevice
     * @return A new Map indicating success or error containing the
     * body generated from the template and the input parameters.
     */
    public static Map<String, Object> prepareNotification(DispatchContext ctx, Map<String, ? extends Object> context) {
        Delegator delegator = ctx.getDelegator();
        String templateName = (String) context.get("templateName");
        Map<String, Object> templateData = UtilGenerics.checkMap(context.get("templateData"));
        String webSiteId = (String) context.get("webSiteId");
        Locale locale = (Locale) context.get("locale");
        Map<String, Object> result = null;
        if (templateData == null) {
            templateData = FastMap.newInstance();
        }

        try {
            // ensure the baseURl is defined
            setBaseUrl(delegator, webSiteId, templateData);

            // initialize the template reader and processor
            URL templateUrl = UtilURL.fromResource(templateName);

            if (templateUrl == null) {
                Debug.logError("Problem getting the template URL: " + templateName + " not found", module);
                return ServiceUtil.returnError(UtilProperties.getMessage(resource, "CommonNotifyEmailProblemFindingTemplate", locale));
            }

            // process the template with the given data and write
            // the email body to the String buffer
            Writer writer = new StringWriter();
            FreeMarkerWorker.renderTemplate(templateUrl.toExternalForm(), templateData, writer);

            // extract the newly created body for the notification email
            String notificationBody = writer.toString();

            // generate the successful response
            result = ServiceUtil.returnSuccess(UtilProperties.getMessage(resource, "CommonNotifyEmailMessageBodyGeneratedSuccessfully", locale));
            result.put("body", notificationBody);
        } catch (IOException ie) {
            Debug.logError(ie, "Problems reading template", module);
            result = ServiceUtil.returnError(UtilProperties.getMessage(resource, "CommonNotifyEmailProblemReadingTemplate", locale));
        } catch (TemplateException te) {
            Debug.logError(te, "Problems processing template", module);
            result = ServiceUtil.returnError(UtilProperties.getMessage(resource, "CommonNotifyEmailProblemProcessingTemplate", locale));
        }

        return result;
    }

    /**
     * The expectation is that a lot of notification messages will include
     * a link back to one or more pages in the system, which will require knowledge
     * of the base URL to extrapolate. This method will ensure that the
     * <code>baseUrl</code> field is set in the given context.
     * <p>
     * If it has been specified a default <code>baseUrl</code> will be
     * set using a best effort approach. If it is specified in the
     * url.properties configuration files of the system, that will be
     * used, otherwise it will attempt resolve the fully qualified
     * local host name.
     * <p>
     * <i>Note:</i> I thought it might be useful to have some dynamic way
     * of extending the default properties provided by the NotificationService,
     * such as the <code>baseUrl</code>, perhaps using the standard
     * <code>ResourceBundle</code> java approach so that both classes
     * and static files may be invoked.
     *
     * @param context   The context to check and, if necessary, set the
     * <code>baseUrl</code>.
     */
    public static void setBaseUrl(Delegator delegator, String webSiteId, Map<String, Object> context) {
        // If the baseUrl was not specified we can do a best effort instead
        if (!context.containsKey("baseUrl")) {
            StringBuilder httpBase = null;
            StringBuilder httpsBase = null;

            String localServer = null;

            String httpsPort = null;
            String httpsServer = null;
            String httpPort = null;
            String httpServer = null;
            Boolean enableHttps = null;

            try {
                // using just the IP address of localhost if we don't have a defined server
                InetAddress localHost = InetAddress.getLocalHost();
                localServer = localHost.getHostAddress();
            } catch (UnknownHostException hostException) {
                Debug.logWarning(hostException, "Could not determine localhost, using '127.0.0.1'", module);
                localServer = "127.0.0.1";
            }

            // load the properties from the website entity
            GenericValue webSite = null;
            if (webSiteId != null) {
                try {
                    webSite = delegator.findOne("WebSite", UtilMisc.toMap("webSiteId", webSiteId), true);
                    if (webSite != null) {
                        httpsPort = webSite.getString("httpsPort");
                        httpsServer = webSite.getString("httpsHost");
                        httpPort = webSite.getString("httpPort");
                        httpServer = webSite.getString("httpHost");
                        enableHttps = webSite.getBoolean("enableHttps");
                    }
                } catch (GenericEntityException e) {
                    Debug.logWarning(e, "Problems with WebSite entity; using global defaults", module);
                }
            }

            // fill in any missing properties with fields from the global file
            if (UtilValidate.isEmpty(httpsPort)) {
                httpsPort = EntityUtilProperties.getPropertyValue("url.properties", "port.https", "443", delegator);
            }
            if (UtilValidate.isEmpty(httpsServer)) {
                httpsServer = EntityUtilProperties.getPropertyValue("url.properties", "force.https.host", localServer, delegator);
            }
            if (UtilValidate.isEmpty(httpPort)) {
                httpPort = EntityUtilProperties.getPropertyValue("url.properties", "port.http", "80", delegator);
            }
            if (UtilValidate.isEmpty(httpServer)) {
                httpServer = EntityUtilProperties.getPropertyValue("url.properties", "force.http.host", localServer, delegator);
            }
            if (UtilValidate.isEmpty(enableHttps)) {
                enableHttps = (EntityUtilProperties.propertyValueEqualsIgnoreCase("url.properties", "port.https.enabled", "Y", delegator)) ? Boolean.TRUE : Boolean.FALSE;
            }

            if (ClassLoaderContainer.portOffset != 0) {
                Integer httpPortValue = Integer.valueOf(httpPort);
                httpPortValue += ClassLoaderContainer.portOffset;
                httpPort = httpPortValue.toString();
                Integer httpsPortValue = Integer.valueOf(httpsPort);
                httpsPortValue += ClassLoaderContainer.portOffset;
                httpsPort = httpsPortValue.toString();
            }

            // prepare the (non-secure) URL
            httpBase = new StringBuilder("http://");
            httpBase.append(httpServer);
            if (!"80".equals(httpPort)) {
                httpBase.append(":");
                httpBase.append(httpPort);
            }

            // set the base (non-secure) URL for any messages requiring it
            context.put("baseUrl", httpBase.toString());

            if (enableHttps.booleanValue()) {
                // prepare the (secure) URL
                httpsBase = new StringBuilder("https://");
                httpsBase.append(httpsServer);
                if (!"443".equals(httpsPort)) {
                    httpsBase.append(":");
                    httpsBase.append(httpsPort);
                }

                // set the base (secure) URL for any messages requiring it
                context.put("baseSecureUrl", httpsBase.toString());
            } else {
                context.put("baseSecureUrl", httpBase.toString());
            }
        }
    }
}
