/*
 * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 * WSO2 Inc. 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.wso2.carbon.identity.event.handler.notification.email.bean;


import org.wso2.carbon.identity.event.handler.notification.exception.NotificationRuntimeException;
import org.wso2.carbon.email.mgt.model.EmailTemplate;

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Map;

public class Notification implements Serializable {

    private String sendTo;
    private String sendFrom;
    private EmailTemplate template;
    private String subject;
    private String body;
    private String footer;
    private Map<String, String> placeHolderData;

    protected Notification(EmailNotificationBuilder builder) {
        this.sendTo = builder.sendTo;
        this.sendFrom = builder.sendFrom;
        this.template = builder.template;
        this.placeHolderData = builder.placeHolderData;
        this.subject = replaceTags(template.getSubject(), placeHolderData);
        this.body = replaceTags(template.getBody(), placeHolderData);
        this.footer = replaceTags(template.getFooter(), placeHolderData);
    }

    private static String replaceTags(String content, Map<String, String> tagsData) {

        for (Map.Entry<String, String> entry : tagsData.entrySet()) {
            try {
                content = content.replaceAll("\\{\\{url:" + entry.getKey() + "\\}\\}", URLEncoder.encode(entry.getValue(),
                        "UTF-8"));
            } catch (UnsupportedEncodingException e) {
                throw NotificationRuntimeException.error(e.getMessage(), e);
            }
            content = content.replaceAll("\\{\\{" + entry.getKey() + "\\}\\}", entry.getValue());
        }
        return content;
    }

    public String getSendTo() {
        return this.sendTo;
    }

    public String getSendFrom() {
        return this.sendFrom;
    }

    public EmailTemplate getTemplate() {
        return this.template;
    }

    public String getSubject() {
        return this.subject;
    }

    public String getBody() {
        return this.body;
    }

    public String getFooter() {
        return this.footer;
    }

    public static class EmailNotificationBuilder {

        // mandatory attributes
        private String sendTo;
        private String sendFrom;
        private EmailTemplate template;
        private Map<String, String> placeHolderData;

        public EmailNotificationBuilder(String sendTo) {
            this.sendTo = sendTo;
        }

        public void setTemplate(EmailTemplate template) {
            this.template = template;
        }

        public void setSendFrom(String sendFrom) {
            this.sendFrom = sendFrom;
        }

        public void setPlaceHolderData(Map<String, String> placeHolderData) {
            this.placeHolderData = placeHolderData;
        }

        public void addPlaceHolderData(String key, String value) {
            this.placeHolderData.put(key, value);
        }

        public Notification build() {
            return new Notification(this);
        }
    }

}

@@ -1017,16 +1017,48 @@
 til.Map;
+%0Aimport java.util.regex.Matcher;
 %0A%0Apublic
@@ -1968,16 +1968,207 @@
    try %7B
+%0A%0A                // In email templates the placeholders in a URL, are defined in the format of %7B%7Burl:key%7D%7D -%0A                // eg:%7B%7Burl:user-name%7D%7D, So that the values should be URL Encoded
 %0A       
@@ -2455,32 +2455,141 @@
 );%0A            %7D
+%0A%0A            // Backslashes (%5C) and dollar signs ($) in the replacement string is not treated as a literals.
 %0A            con
@@ -2652,21 +2652,67 @@
 %5C%7D%5C%5C%7D%22, 
-entry
+Matcher.quoteReplacement(entry%0A                    
 .getValu
@@ -2715,16 +2715,17 @@
 Value())
+)
 ;%0A      

Fix IllegalArgumentException when replacing strings Resolves https://github.com/wso2/product-is/issues/3057