/*******************************************************************************
 * 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.apache.ofbiz.base.util;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.owasp.esapi.codecs.Codec;
import org.owasp.esapi.codecs.HTMLEntityCodec;
import org.owasp.esapi.codecs.PercentCodec;
import org.owasp.esapi.codecs.XMLEntityCodec;
import org.owasp.html.HtmlPolicyBuilder;
import org.owasp.html.PolicyFactory;
import org.owasp.html.Sanitizers;

public class UtilCodec {
    private static final String module = UtilCodec.class.getName();
    private static final HtmlEncoder htmlEncoder = new HtmlEncoder();
    private static final XmlEncoder xmlEncoder = new XmlEncoder();
    private static final StringEncoder stringEncoder = new StringEncoder();
    private static final UrlCodec urlCodec = new UrlCodec();
    private static final List<Codec> codecs;
    static {
        List<Codec> tmpCodecs = new ArrayList<Codec>();
        tmpCodecs.add(new HTMLEntityCodec());
        tmpCodecs.add(new PercentCodec());
        codecs = Collections.unmodifiableList(tmpCodecs);
    }

    @SuppressWarnings("serial")
    public static class IntrusionException extends GeneralRuntimeException {
        public IntrusionException(String message) {
            super(message);
        }
    }

    public static interface SimpleEncoder {
        public String encode(String original);
        /**
         * @deprecated Use {@link #sanitize(String,String)} instead
         */
        public String sanitize(String outString); // Only really useful with HTML, else it simply calls encode() method 
        public String sanitize(String outString, String contentTypeId); // Only really useful with HTML, else it simply calls encode() method 
    }

    public static interface SimpleDecoder {
        public String decode(String original);
    }

    public static class HtmlEncoder implements SimpleEncoder {
        private static final char[] IMMUNE_HTML = {',', '.', '-', '_', ' '};
        private HTMLEntityCodec htmlCodec = new HTMLEntityCodec();
        public String encode(String original) {
            if (original == null) {
                return null;
            }
            return htmlCodec.encode(IMMUNE_HTML, original);
        }
        /**
         * @deprecated Use {@link #sanitize(String,String)} instead
         */
        public String sanitize(String original) {
            return sanitize(original, null);
        }
        public String sanitize(String original, String contentTypeId) {
            if (original == null) {
                return null;
            }
            PolicyFactory sanitizer = Sanitizers.FORMATTING.and(Sanitizers.BLOCKS).and(Sanitizers.IMAGES).and(Sanitizers.LINKS).and(Sanitizers.STYLES);

            if (UtilProperties.getPropertyAsBoolean("owasp", "sanitizer.permissive.policy", false)) {// TODO to be improved to use a (or several) contentTypeId/s if possible 
                sanitizer = sanitizer.and(PERMISSIVE_POLICY);
            }
            if ("REPORT_MASTER".equals(contentTypeId)) {
                sanitizer = sanitizer.and(BIRT_REPORT_BUILDER_GENERATION_POLICY);
            }
            if ("REPORT".equals(contentTypeId)) {
                sanitizer = sanitizer.and(BIRT_REPORT_BUILDER_USAGE_POLICY);
            }
            return sanitizer.sanitize(original);
        }
        // Given as an example based on rendering cmssite as it was before using the sanitizer.
        // To use the PERMISSIVE_POLICY set sanitizer.permissive.policy to true. 
        // Note that I was unable to render </html> and </body>. I guess because <html> and <body> are not sanitized in 1st place (else the sanitizer makes some damages I found)
        // You might even want to adapt the PERMISSIVE_POLICY to your needs... Be sure to check https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet before...
        public static final PolicyFactory PERMISSIVE_POLICY = new HtmlPolicyBuilder()
                .allowWithoutAttributes("html", "body")
                .allowAttributes("id", "class").globally()
                .allowElements("div", "center", "span", "table", "td")
                .allowWithoutAttributes("html", "body", "div", "span", "table", "td")
                .allowAttributes("width").onElements("table")
                .toFactory();
        // This is the PolicyFactory used for the Birt Report Builder generation feature ("REPORT_MASTER" contentTypeId)
        // It allows to create the OOTB Birt Report Builder example.
        // You might need to enhance it for your needs but normally you should not
        // In any case be sure to check https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet before changing things here...
        public static final PolicyFactory BIRT_REPORT_BUILDER_GENERATION_POLICY = new HtmlPolicyBuilder()
                .allowWithoutAttributes("html", "body")
                .allowElements("div", "span", "table", "tr", "td")
                .allowElements("form", "input", "textarea", "label", "select", "option")
                .allowAttributes("id", "class", "name", "value", "onclick").globally()
                .allowAttributes("width", "cellspacing").onElements("table")
                .allowAttributes("type", "size", "maxlength").onElements("input")
                .allowAttributes("cols", "rows").onElements("textarea")
                .allowAttributes("class").onElements("td")
                .allowAttributes("method").onElements("form")
                .toFactory();
        // This is the PolicyFactory used for the Birt Report Builder usage feature.  ("REPORT" contentTypeId)
        // It allows to use the OOTB Birt Report Builder example.
        // You might need to enhance it for your needs but normally you should not
        // In any case be sure to check https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet before changing things here...
        public static final PolicyFactory BIRT_REPORT_BUILDER_USAGE_POLICY = new HtmlPolicyBuilder()
                .allowWithoutAttributes("html", "body")
                .allowElements("div", "span", "table", "tr", "td", "script")
                .allowElements("form", "input", "textarea", "label", "select", "option")
                .allowAttributes("id", "class", "name", "value", "onclick").globally()
                .allowAttributes("width", "cellspacing").onElements("table")
                .allowAttributes("type", "size", "maxlength").onElements("input")
                .allowAttributes("cols", "rows").onElements("textarea")
                .allowAttributes("class").onElements("td")
                .allowAttributes("method", "onsubmit").onElements("form")
                .toFactory();
    }

    public static class XmlEncoder implements SimpleEncoder {
        private static final char[] IMMUNE_XML = {',', '.', '-', '_', ' '};
        private XMLEntityCodec xmlCodec = new XMLEntityCodec();
        public String encode(String original) {
            if (original == null) {
                   return null;
               }
               return xmlCodec.encode(IMMUNE_XML, original);
        }
        /**
         * @deprecated Use {@link #sanitize(String,String)} instead
         */
        public String sanitize(String original) {
            return sanitize(original, null);
        }
        public String sanitize(String original, String contentTypeId) {
            return encode(original);
        }
    }

    public static class UrlCodec implements SimpleEncoder, SimpleDecoder {
        public String encode(String original) {
            try {
                return URLEncoder.encode(original, "UTF-8");
            } catch (UnsupportedEncodingException ee) {
                Debug.logError(ee, module);
                return null;
            }
        }
        /**
         * @deprecated Use {@link #sanitize(String,String)} instead
         */
        public String sanitize(String original) {
            return sanitize(original, null);
        }
        public String sanitize(String original, String contentTypeId) {
            return encode(original);
        }

        public String decode(String original) {
            try {
                String canonical = canonicalize(original);
                return URLDecoder.decode(canonical, "UTF-8");
            } catch (UnsupportedEncodingException ee) {
                Debug.logError(ee, module);
                return null;
            }
        }
    }

    public static class StringEncoder implements SimpleEncoder {
        public String encode(String original) {
            if (original != null) {
                original = original.replace("\"", "\\\"");
            }
            return original;
        }
        /**
         * @deprecated Use {@link #sanitize(String,String)} instead
         */
        public String sanitize(String original) {
            return sanitize(original, null);
        }
        public String sanitize(String original, String contentTypeId) {
            return encode(original);
        }
    }

    // ================== Begin General Functions ==================

    public static SimpleEncoder getEncoder(String type) {
        if ("url".equals(type)) {
            return urlCodec;
        } else if ("xml".equals(type)) {
            return xmlEncoder;
        } else if ("html".equals(type)) {
            return htmlEncoder;
        } else if ("string".equals(type)) {
            return stringEncoder;
        } else {
            return null;
        }
    }

    public static SimpleDecoder getDecoder(String type) {
        if ("url".equals(type)) {
            return urlCodec;
        } else {
            return null;
        }
    }

    public static String canonicalize(String value) throws IntrusionException {
        return canonicalize(value, false, false);
    }

    public static String canonicalize(String value, boolean strict) throws IntrusionException {
        return canonicalize(value, strict, strict);
    }

    public static String canonicalize(String input, boolean restrictMultiple, boolean restrictMixed) {
        if (input == null) {
            return null;
        }

        String working = input;
        Codec codecFound = null;
        int mixedCount = 1;
        int foundCount = 0;
        boolean clean = false;
        while (!clean) {
            clean = true;

            // try each codec and keep track of which ones work
            Iterator<Codec> i = codecs.iterator();
            while (i.hasNext()) {
                Codec codec = i.next();
                String old = working;
                working = codec.decode(working);
                if (!old.equals(working)) {
                    if (codecFound != null && codecFound != codec) {
                        mixedCount++;
                    }
                    codecFound = codec;
                    if (clean) {
                        foundCount++;
                    }
                    clean = false;
                }
            }
        }

        // do strict tests and handle if any mixed, multiple, nested encoding were found
        if (foundCount >= 2 && mixedCount > 1) {
            if (restrictMultiple || restrictMixed) {
                throw new IntrusionException("Input validation failure");
            } else {
                Debug.logWarning("Multiple (" + foundCount + "x) and mixed encoding (" + mixedCount + "x) detected in " + input, module);
            }
        } else if (foundCount >= 2) {
            if (restrictMultiple) {
                throw new IntrusionException("Input validation failure");
            } else {
                Debug.logWarning("Multiple (" + foundCount + "x) encoding detected in " + input, module);
            }
        } else if (mixedCount > 1) {
            if (restrictMixed) {
                throw new IntrusionException("Input validation failure");
            } else {
                Debug.logWarning("Mixed encoding (" + mixedCount + "x) detected in " + input, module);
            }
        }
        return working;
    }

    /**
     * Uses a black-list approach for necessary characters for HTML.
     * <p>
     * Does not allow various characters (after canonicalization), including
     * "&lt;", "&gt;", "&amp;" (if not followed by a space), and "%" (if not 
     * followed by a space).
     *
     * @param value
     * @param errorMessageList
     */
    public static String checkStringForHtmlStrictNone(String valueName, String value, List<String> errorMessageList) {
        if (UtilValidate.isEmpty(value)) return value;

        // canonicalize, strict (error on double-encoding)
        try {
            value = canonicalize(value, true);
        } catch (IntrusionException e) {
            // NOTE: using different log and user targeted error messages to allow the end-user message to be less technical
            Debug.logError("Canonicalization (format consistency, character escaping that is mixed or double, etc) error for attribute named [" + valueName + "], String [" + value + "]: " + e.toString(), module);
            errorMessageList.add("In field [" + valueName + "] found character escaping (mixed or double) that is not allowed or other format consistency error: " + e.toString());
        }

        // check for "<", ">"
        if (value.indexOf("<") >= 0 || value.indexOf(">") >= 0) {
            errorMessageList.add("In field [" + valueName + "] less-than (<) and greater-than (>) symbols are not allowed.");
        }

        // TODO: anything else to check for that can be used to get HTML or JavaScript going without these characters?

        return value;
    }

    /**
     * A simple Map wrapper class that will do HTML encoding. To be used for passing a Map to something that will expand Strings with it as a context, etc.
     */
    public static class HtmlEncodingMapWrapper<K> implements Map<K, Object> {
        public static <K> HtmlEncodingMapWrapper<K> getHtmlEncodingMapWrapper(Map<K, Object> mapToWrap, SimpleEncoder encoder) {
            if (mapToWrap == null) return null;

            HtmlEncodingMapWrapper<K> mapWrapper = new HtmlEncodingMapWrapper<K>();
            mapWrapper.setup(mapToWrap, encoder);
            return mapWrapper;
        }

        protected Map<K, Object> internalMap = null;
        protected SimpleEncoder encoder = null;
        protected HtmlEncodingMapWrapper() { }

        public void setup(Map<K, Object> mapToWrap, SimpleEncoder encoder) {
            this.internalMap = mapToWrap;
            this.encoder = encoder;
        }
        public void reset() {
            this.internalMap = null;
            this.encoder = null;
        }

        public int size() { return this.internalMap.size(); }
        public boolean isEmpty() { return this.internalMap.isEmpty(); }
        public boolean containsKey(Object key) { return this.internalMap.containsKey(key); }
        public boolean containsValue(Object value) { return this.internalMap.containsValue(value); }
        public Object get(Object key) {
            Object theObject = this.internalMap.get(key);
            if (theObject instanceof String) {
                if (this.encoder != null) {
                    return encoder.encode((String) theObject);
                } else {
                    return UtilCodec.getEncoder("html").encode((String) theObject);
                }
            } else if (theObject instanceof Map<?, ?>) {
                return HtmlEncodingMapWrapper.getHtmlEncodingMapWrapper(UtilGenerics.<K, Object>checkMap(theObject), this.encoder);
            }
            return theObject;
        }
        public Object put(K key, Object value) { return this.internalMap.put(key, value); }
        public Object remove(Object key) { return this.internalMap.remove(key); }
        public void putAll(Map<? extends K, ? extends Object> arg0) { this.internalMap.putAll(arg0); }
        public void clear() { this.internalMap.clear(); }
        public Set<K> keySet() { return this.internalMap.keySet(); }
        public Collection<Object> values() { return this.internalMap.values(); }
        public Set<Map.Entry<K, Object>> entrySet() { return this.internalMap.entrySet(); }
        @Override
        public String toString() { return this.internalMap.toString(); }
    }

}
