/*******************************************************************************
 * 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.product.category;

import java.io.FileInputStream;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.ParserConfigurationException;

import javolution.util.FastList;
import javolution.util.FastMap;
import javolution.util.FastSet;

import org.apache.oro.text.regex.MalformedPatternException;
import org.apache.oro.text.regex.Pattern;
import org.apache.oro.text.regex.Perl5Compiler;
import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.StringUtil;
import org.ofbiz.base.util.UtilURL;
import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.base.util.UtilXml;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * SeoConfigUtil - SEO Configuration file utility.
 * 
 */
public class SeoConfigUtil {
    private static final String module = SeoConfigUtil.class.getName();
    private static Perl5Compiler perlCompiler = new Perl5Compiler();
    private static boolean isInitialed = false;
    private static boolean categoryUrlEnabled = true;
    private static boolean categoryNameEnabled = false;
    private static String categoryUrlSuffix = null;
    public static final String DEFAULT_REGEXP = "^.*/.*$";
    private static Pattern regexpIfMatch = null;
    private static boolean useUrlRegexp = false;
    private static boolean jSessionIdAnonEnabled = false;
    private static boolean jSessionIdUserEnabled = false;
    private static Map<String, String> seoReplacements = null;
    private static Map<String, Pattern> seoPatterns = null;
    private static Map<String, String> forwardReplacements = null;
    private static Map<String, Integer> forwardResponseCodes = null;
    private static Map<String, String> charFilters = null;
    private static List<Pattern> userExceptionPatterns = null;
    private static Set<String> allowedContextPaths = null;
    private static Map<String, String> specialProductIds = null;
    public static final String ELEMENT_REGEXPIFMATCH = "regexpifmatch";
    public static final String ELEMENT_URL_CONFIG = "url-config";
    public static final String ELEMENT_DESCRIPTION = "description";
    public static final String ELEMENT_FORWARD = "forward";
    public static final String ELEMENT_SEO = "seo";
    public static final String ELEMENT_URLPATTERN = "url-pattern";
    public static final String ELEMENT_REPLACEMENT = "replacement";
    public static final String ELEMENT_RESPONSECODE = "responsecode";
    public static final String ELEMENT_JSESSIONID = "jsessionid";
    public static final String ELEMENT_ANONYMOUS = "anonymous";
    public static final String ELEMENT_VALUE = "value";
    public static final String ELEMENT_USER = "user";
    public static final String ELEMENT_EXCEPTIONS = "exceptions";
    public static final String ELEMENT_CHAR_FILTERS = "char-filters";
    public static final String ELEMENT_CHAR_FILTER = "char-filter";
    public static final String ELEMENT_CHARACTER_PATTERN = "character-pattern";
    public static final String ELEMENT_CATEGORY_URL = "category-url";
    public static final String ELEMENT_ALLOWED_CONTEXT_PATHS = "allowed-context-paths";
    public static final String ELEMENT_CATEGORY_NAME = "category-name";
    public static final String ELEMENT_CATEGORY_URL_SUFFIX = "category-url-suffix";
    public static final String SEO_CONFIG_FILENAME = "SeoConfig.xml";
    public static final int DEFAULT_RESPONSECODE = HttpServletResponse.SC_MOVED_PERMANENTLY;
    public static final String DEFAULT_ANONYMOUS_VALUE = "disable";
    public static final String DEFAULT_USER_VALUE = "disable";
    public static final String DEFAULT_CATEGORY_URL_VALUE = "enable";
    public static final String DEFAULT_CATEGORY_NAME_VALUE = "disable";
    public static final String ALLOWED_CONTEXT_PATHS_SEPERATOR = ":";

    /**
     * Initialize url regular express configuration.
     * 
     * @return result to indicate the status of initialization.
     */
    public static void init() {
        FileInputStream configFileIS = null;
        String result = "success";
        seoPatterns = new HashMap<String, Pattern>();
        seoReplacements = new HashMap<String, String>();
        forwardReplacements = new HashMap<String, String>();
        forwardResponseCodes = new HashMap<String, Integer>();
        userExceptionPatterns = FastList.newInstance();
        specialProductIds = FastMap.newInstance();
        charFilters = FastMap.newInstance();
        try {
            URL seoConfigFilename = UtilURL.fromResource(SEO_CONFIG_FILENAME);
            Document configDoc = UtilXml.readXmlDocument(seoConfigFilename, false);
            Element rootElement = configDoc.getDocumentElement();

            String regexIfMatch = UtilXml.childElementValue(rootElement, ELEMENT_REGEXPIFMATCH, DEFAULT_REGEXP);
            Debug.logInfo("Parsing " + regexIfMatch, module);
            try {
                regexpIfMatch = perlCompiler.compile(regexIfMatch, Perl5Compiler.READ_ONLY_MASK);
            } catch (MalformedPatternException e1) {
                Debug.logWarning(e1, "Error while parsing " + regexIfMatch, module);
            }

            // parse category-url element
            try {
                Element categoryUrlElement = UtilXml.firstChildElement(rootElement, ELEMENT_CATEGORY_URL);
                Debug.logInfo("Parsing " + ELEMENT_CATEGORY_URL + " [" + (categoryUrlElement != null) + "]:", module);
                if (categoryUrlElement != null) {
                    String enableCategoryUrlValue = UtilXml.childElementValue(categoryUrlElement, ELEMENT_VALUE, DEFAULT_CATEGORY_URL_VALUE);
                    if (DEFAULT_CATEGORY_URL_VALUE.equalsIgnoreCase(enableCategoryUrlValue)) {
                        categoryUrlEnabled = true;
                    } else {
                        categoryUrlEnabled = false;
                    }
                    
                    if (categoryUrlEnabled) {
                        String allowedContextValue = UtilXml.childElementValue(categoryUrlElement, ELEMENT_ALLOWED_CONTEXT_PATHS, null);
                        allowedContextPaths = FastSet.newInstance();
                        if (UtilValidate.isNotEmpty(allowedContextValue)) {
                            List<String> allowedContextPathList = StringUtil.split(allowedContextValue, ALLOWED_CONTEXT_PATHS_SEPERATOR);
                            for (String path : allowedContextPathList) {
                                if (UtilValidate.isNotEmpty(path)) {
                                    path = path.trim();
                                    if (!allowedContextPaths.contains(path)) {
                                        allowedContextPaths.add(path);
                                        Debug.logInfo("  " + ELEMENT_ALLOWED_CONTEXT_PATHS + ": " + path, module);
                                    }
                                }
                            }
                        }
                        
                        String categoryNameValue = UtilXml.childElementValue(categoryUrlElement, ELEMENT_CATEGORY_NAME, DEFAULT_CATEGORY_NAME_VALUE);
                        if (DEFAULT_CATEGORY_NAME_VALUE.equalsIgnoreCase(categoryNameValue)) {
                            categoryNameEnabled = false;
                        } else {
                            categoryNameEnabled = true;
                        }
                        Debug.logInfo("  " + ELEMENT_CATEGORY_NAME + ": " + categoryNameEnabled, module);

                        categoryUrlSuffix = UtilXml.childElementValue(categoryUrlElement, ELEMENT_CATEGORY_URL_SUFFIX, null);
                        if (UtilValidate.isNotEmpty(categoryUrlSuffix)) {
                            categoryUrlSuffix = categoryUrlSuffix.trim();
                            if (categoryUrlSuffix.contains("/")) {
                                categoryUrlSuffix = null;
                            }
                        }
                        Debug.logInfo("  " + ELEMENT_CATEGORY_URL_SUFFIX + ": " + categoryUrlSuffix, module);
                    }
                }
            } catch (NullPointerException e) {
                // no "category-url" element
                Debug.logWarning("No category-url element found in " + seoConfigFilename.toString(), module);
            }

            // parse jsessionid element
            try {
                Element jSessionId = UtilXml.firstChildElement(rootElement, ELEMENT_JSESSIONID);
                Debug.logInfo("Parsing " + ELEMENT_JSESSIONID + " [" + (jSessionId != null) + "]:", module);
                if (jSessionId != null) {
                    Element anonymous = UtilXml.firstChildElement(jSessionId, ELEMENT_ANONYMOUS);
                    if (anonymous != null) {
                        String anonymousValue = UtilXml.childElementValue(anonymous, ELEMENT_VALUE, DEFAULT_ANONYMOUS_VALUE);
                        if (DEFAULT_ANONYMOUS_VALUE.equalsIgnoreCase(anonymousValue)) {
                            jSessionIdAnonEnabled = false;
                        } else {
                            jSessionIdAnonEnabled = true;
                        }
                    } else {
                        jSessionIdAnonEnabled = Boolean.valueOf(DEFAULT_ANONYMOUS_VALUE).booleanValue();
                    }
                    Debug.logInfo("  " + ELEMENT_ANONYMOUS + ": " + jSessionIdAnonEnabled, module);
                    
                    Element user = UtilXml.firstChildElement(jSessionId, ELEMENT_USER);
                    if (user != null) {
                        String userValue = UtilXml.childElementValue(user, ELEMENT_VALUE, DEFAULT_USER_VALUE);
                        if (DEFAULT_USER_VALUE.equalsIgnoreCase(userValue)) {
                            jSessionIdUserEnabled = false;
                        } else {
                            jSessionIdUserEnabled = true;
                        }

                        Element exceptions = UtilXml.firstChildElement(user, ELEMENT_EXCEPTIONS);
                        if (exceptions != null) {
                            Debug.logInfo("  " + ELEMENT_EXCEPTIONS + ": ", module);
                            List<? extends Element> exceptionUrlPatterns = UtilXml.childElementList(exceptions, ELEMENT_URLPATTERN);
                            for (int i = 0; i < exceptionUrlPatterns.size(); i++) {
                                Element element = exceptionUrlPatterns.get(i);
                                String urlpattern = element.getTextContent();
                                if (UtilValidate.isNotEmpty(urlpattern)) {
                                    try {
                                        Pattern pattern = perlCompiler.compile(urlpattern, Perl5Compiler.READ_ONLY_MASK);
                                        userExceptionPatterns.add(pattern);
                                        Debug.logInfo("    " + ELEMENT_URLPATTERN + ": " + urlpattern, module);
                                    } catch (MalformedPatternException e) {
                                        Debug.logWarning("Can NOT parse " + urlpattern + " in element " + ELEMENT_URLPATTERN + " of " + ELEMENT_EXCEPTIONS + ". Error: " + e.getMessage(), module);
                                    }
                                }
                            }
                        }
                    } else {
                        jSessionIdUserEnabled = Boolean.valueOf(DEFAULT_USER_VALUE).booleanValue();
                    }
                    Debug.logInfo("  " + ELEMENT_USER + ": " + jSessionIdUserEnabled, module);
                }
            } catch (NullPointerException e) {
                Debug.logWarning("No jsessionid element found in " + seoConfigFilename.toString(), module);
            }
            
            // parse url-config elements
            try {
                NodeList configs = rootElement.getElementsByTagName(ELEMENT_URL_CONFIG);
                Debug.logInfo("Parsing " + ELEMENT_URL_CONFIG, module);
                for (int j = 0; j < configs.getLength(); j++) {
                    Element config = (Element) configs.item(j);
                    String urlpattern = UtilXml.childElementValue(config, ELEMENT_URLPATTERN, null);
                    if (UtilValidate.isEmpty(urlpattern)) {
                        continue;
                    }
                    Debug.logInfo("  " + ELEMENT_URLPATTERN + ": " + urlpattern, module);
                    Pattern pattern;
                    try {
                        pattern = perlCompiler.compile(urlpattern, Perl5Compiler.READ_ONLY_MASK);
                        seoPatterns.put(urlpattern, pattern);
                    } catch (MalformedPatternException e) {
                        Debug.logWarning("Error while creating parttern for seo url-pattern: " + urlpattern, module);
                        continue;
                    }
                    
                    // construct seo patterns
                    Element seo = UtilXml.firstChildElement(config, ELEMENT_SEO);
                    if (UtilValidate.isNotEmpty(seo)) {
                        String replacement = UtilXml.childElementValue(seo, ELEMENT_REPLACEMENT, null);
                        if (UtilValidate.isNotEmpty(replacement)) {
                            seoReplacements.put(urlpattern, replacement);
                            Debug.logInfo("    " + ELEMENT_SEO + " " + ELEMENT_REPLACEMENT + ": " + replacement, module);
                        }
                    }

                    // construct forward patterns
                    Element forward = UtilXml.firstChildElement(config, ELEMENT_FORWARD);
                    if (UtilValidate.isNotEmpty(forward)) {
                        String replacement = UtilXml.childElementValue(forward, ELEMENT_REPLACEMENT, null);
                        String responseCode = UtilXml.childElementValue(forward,
                                ELEMENT_RESPONSECODE, String.valueOf(DEFAULT_RESPONSECODE));
                        if (UtilValidate.isNotEmpty(replacement)) {
                            forwardReplacements.put(urlpattern, replacement);
                            Debug.logInfo("    " + ELEMENT_FORWARD + " " + ELEMENT_REPLACEMENT + ": " + replacement, module);
                            if (UtilValidate.isNotEmpty(responseCode)) {
                                Integer responseCodeInt = DEFAULT_RESPONSECODE;
                                try {
                                    responseCodeInt = Integer.valueOf(responseCode);
                                } catch (NumberFormatException nfe) {
                                    Debug.logWarning(nfe, "Error while parsing response code number: " + responseCode, module);
                                }
                                forwardResponseCodes.put(urlpattern, responseCodeInt);
                                Debug.logInfo("    " + ELEMENT_FORWARD + " " + ELEMENT_RESPONSECODE + ": " + responseCodeInt, module);
                            }
                        }
                    }
                }
            } catch (NullPointerException e) {
                // no "url-config" element
                Debug.logWarning("No " + ELEMENT_URL_CONFIG + " element found in " + seoConfigFilename.toString(), module);
            }

            // parse char-filters elements
            try {
                NodeList nameFilterNodes = rootElement
                        .getElementsByTagName(ELEMENT_CHAR_FILTER);
                Debug.logInfo("Parsing " + ELEMENT_CHAR_FILTER + ": ", module);
                for (int i = 0; i < nameFilterNodes.getLength(); i++) {
                    Element element = (Element) nameFilterNodes.item(i);
                    String charaterPattern = UtilXml.childElementValue(element, ELEMENT_CHARACTER_PATTERN, null);
                    String replacement = UtilXml.childElementValue(element, ELEMENT_REPLACEMENT, null);
                    if (UtilValidate.isNotEmpty(charaterPattern)
                            && UtilValidate.isNotEmpty(replacement)) {
                        try {
                            perlCompiler.compile(charaterPattern, Perl5Compiler.READ_ONLY_MASK);
                            charFilters.put(charaterPattern, replacement);
                            Debug.logInfo("  " + ELEMENT_CHARACTER_PATTERN + ": " + charaterPattern, module);
                            Debug.logInfo("  " + ELEMENT_REPLACEMENT + ": " + replacement, module);
                        } catch (MalformedPatternException e) {
                            // skip this filter (character-pattern replacement) if any error happened
                            Debug.logWarning(e, "Error while parsing " + ELEMENT_CHARACTER_PATTERN + ": " + charaterPattern, module);
                        }
                    }
                }
            } catch (NullPointerException e) {
                // no "char-filters" element
                Debug.logWarning("No " + ELEMENT_CHAR_FILTER + " element found in " + seoConfigFilename.toString(), module);
            }
        } catch (SAXException e) {
            result = "error";
            Debug.logError(e, module);
        } catch (ParserConfigurationException e) {
            result = "error";
            Debug.logError(e, module);
        } catch (IOException e) {
            result = "error";
            Debug.logError(e, module);
        } finally {
            if (configFileIS != null) {
                try {
                    configFileIS.close();
                } catch (IOException e) {
                    result = "error";
                    Debug.logError(e, module);
                }
            }
        }
        if (seoReplacements.keySet().isEmpty()) {
            useUrlRegexp = false;
        } else {
            useUrlRegexp = true;
        }
        if (result.equals("success")) {
            isInitialed = true;
        }
    }
    
    /**
     * Check whether the configuration file has been read.
     * 
     * @return a boolean value to indicate whether the configuration file has been read.
     */
    public static boolean isInitialed() {
        return isInitialed;
    }

    /**
     * Check whether url regexp should be used.
     * 
     * @return a boolean value to indicate whether url regexp should be used.
     */
    public static boolean checkUseUrlRegexp() {
        return useUrlRegexp;
    }

    /**
     * Get the general regexp pattern.
     * 
     * @return the general regexp pattern.
     */
    public static Pattern getGeneralRegexpPattern() {
        return regexpIfMatch;
    }
    
    /**
     * Check whether category url is enabled.
     * 
     * @return a boolean value to indicate whether category url is enabled.
     */
    public static boolean checkCategoryUrl() {
        return categoryUrlEnabled;
    }

    /**
     * Check whether the context path is enabled.
     * 
     * @return a boolean value to indicate whether the context path is enabled.
     */
    public static boolean isCategoryUrlEnabled(String contextPath) {
        if (contextPath == null) {
            return false;
        }
        if (UtilValidate.isEmpty(contextPath)) {
            contextPath = "/";
        }
        if (categoryUrlEnabled) {
            if (allowedContextPaths.contains(contextPath.trim())) {
                return true;
            } else {
                return false;
            }
        }
        return false;
    }

    /**
     * Check whether category name is enabled.
     * 
     * @return a boolean value to indicate whether category name is enabled.
     */
    public static boolean isCategoryNameEnabled() {
        return categoryNameEnabled;
    }

    /**
     * Get category url suffix.
     * 
     * @return String category url suffix.
     */
    public static String getCategoryUrlSuffix() {
        return categoryUrlSuffix;
    }

    /**
     * Check whether jsessionid is enabled for anonymous.
     * 
     * @return a boolean value to indicate whether jsessionid is enabled for anonymous.
     */
    public static boolean isJSessionIdAnonEnabled() {
        return jSessionIdAnonEnabled;
    }

    /**
     * Check whether jsessionid is enabled for user.
     * 
     * @return a boolean value to indicate whether jsessionid is enabled for user.
     */
    public static boolean isJSessionIdUserEnabled() {
        return jSessionIdUserEnabled;
    }

    /**
     * Get user exception url pattern configures.
     * 
     * @return user exception url pattern configures (java.util.List<Pattern>)
     */
    public static List<Pattern> getUserExceptionPatterns() {
        return userExceptionPatterns;
    }

    /**
     * Get char filters.
     * 
     * @return char filters (java.util.Map<String, String>)
     */
    public static Map<String, String> getCharFilters() {
        return charFilters;
    }

    /**
     * Get seo url pattern configures.
     * 
     * @return seo url pattern configures (java.util.Map<String, Pattern>)
     */
    public static Map<String, Pattern> getSeoPatterns() {
        return seoPatterns;
    }

    /**
     * Get seo replacement configures.
     * 
     * @return seo replacement configures (java.util.Map<String, String>)
     */
    public static Map<String, String> getSeoReplacements() {
        return seoReplacements;
    }

    /**
     * Get forward replacement configures.
     * 
     * @return forward replacement configures (java.util.Map<String, String>)
     */
    public static Map<String, String> getForwardReplacements() {
        return forwardReplacements;
    }

    /**
     * Get forward response codes.
     * 
     * @return forward response code configures (java.util.Map<String, Integer>)
     */
    public static Map<String, Integer> getForwardResponseCodes() {
        return forwardResponseCodes;
    }

    /**
     * Check whether a product id is in the special list. If we cannot get a product from a lower cased
     * or upper cased product id, then it's special.
     * 
     * @return boolean to indicate whether the product id is special.
     */
    @Deprecated
    public static boolean isSpecialProductId(String productId) {
        return specialProductIds.containsKey(productId);
    }

    /**
     * Add a special product id to the special list.
     * 
     * @param productId a product id get from database.
     * @return true to indicate it has been added to special product id; false to indicate it's not special.
     * @throws Exception to indicate there's already same lower cased product id in the list but value is a different product id.
     */
    @Deprecated
    public static boolean addSpecialProductId(String productId) throws Exception {
        if (productId.toLowerCase().equals(productId) || productId.toUpperCase().equals(productId)) {
            return false;
        }
        if (isSpecialProductId(productId.toLowerCase())) {
            if (specialProductIds.containsValue(productId)) {
                return true;
            } else {
                throw new Exception("This product Id cannot be lower cased for SEO URL purpose: " + productId);
            }
        }
        specialProductIds.put(productId.toLowerCase(), productId);
        return true;
    }
    
    /**
     * Get a product id is in the special list.
     * 
     * @return String of the original product id
     */
    @Deprecated
    public static String getSpecialProductId(String productId) {
        return specialProductIds.get(productId);
    }
}
