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

import java.io.IOException;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.base.util.StringUtil;
import org.apache.ofbiz.base.util.StringUtil.StringWrapper;
import org.apache.ofbiz.base.util.UtilValidate;
import org.apache.ofbiz.common.UrlServletHelper;
import org.apache.ofbiz.entity.Delegator;
import org.apache.ofbiz.entity.GenericEntityException;
import org.apache.ofbiz.entity.GenericValue;
import org.apache.ofbiz.entity.condition.EntityCondition;
import org.apache.ofbiz.entity.util.EntityQuery;
import org.apache.ofbiz.entity.util.EntityUtil;
import org.apache.ofbiz.product.product.ProductContentWrapper;
import org.apache.ofbiz.webapp.WebAppUtil;

public class CatalogUrlFilter implements Filter {

    public final static String module = CatalogUrlFilter.class.getName();
    
    public static final String PRODUCT_REQUEST = "product";
    public static final String CATEGORY_REQUEST = "category";
    
    protected static String defaultLocaleString = null;
    protected static String redirectUrl = null;

    protected FilterConfig config;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.config = filterConfig;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        Delegator delegator = (Delegator) httpRequest.getSession().getServletContext().getAttribute("delegator");
        
        // set initial parameters
        String initDefaultLocalesString = config.getInitParameter("defaultLocaleString");
        String initRedirectUrl = config.getInitParameter("redirectUrl");
        defaultLocaleString = UtilValidate.isNotEmpty(initDefaultLocalesString) ? initDefaultLocalesString : "";
        redirectUrl = UtilValidate.isNotEmpty(initRedirectUrl) ? initRedirectUrl : "";
        
        String pathInfo = httpRequest.getServletPath();
        if (UtilValidate.isNotEmpty(pathInfo)) {
            List<String> pathElements = StringUtil.split(pathInfo, "/");
            String alternativeUrl = pathElements.get(0);
            
            String productId = null;
            String productCategoryId = null;
            String urlContentId = null;
            try {
                // look for productId
                if (alternativeUrl.endsWith("-p")) {
                    List<EntityCondition> productContentConds = new LinkedList<EntityCondition>();
                    productContentConds.add(EntityCondition.makeCondition("productContentTypeId", "ALTERNATIVE_URL"));
                    productContentConds.add(EntityUtil.getFilterByDateExpr());
                    List<GenericValue> productContentInfos = EntityQuery.use(delegator).from("ProductContentAndInfo").where(productContentConds).orderBy("-fromDate").cache(true).queryList();
                    if (UtilValidate.isNotEmpty(productContentInfos)) {
                        for (GenericValue productContentInfo : productContentInfos) {
                            String contentId = (String) productContentInfo.get("contentId");
                            List<GenericValue> ContentAssocDataResourceViewTos = EntityQuery.use(delegator).from("ContentAssocDataResourceViewTo").where("contentIdStart", contentId, "caContentAssocTypeId", "ALTERNATE_LOCALE", "drDataResourceTypeId", "ELECTRONIC_TEXT").cache(true).queryList();
                            if (UtilValidate.isNotEmpty(ContentAssocDataResourceViewTos)) {
                                for (GenericValue ContentAssocDataResourceViewTo : ContentAssocDataResourceViewTos) {
                                    GenericValue ElectronicText = ContentAssocDataResourceViewTo.getRelatedOne("ElectronicText", true);
                                    if (ElectronicText != null) {
                                        String textData = (String) ElectronicText.get("textData");
                                        textData = UrlServletHelper.invalidCharacter(textData);
                                        if (alternativeUrl.matches(textData + ".+$")) {
                                            String productIdStr = null;
                                            productIdStr = alternativeUrl.replace(textData + "-", "");
                                            productIdStr = productIdStr.replace("-p", "");
                                            String checkProductId = (String) productContentInfo.get("productId");
                                            if (productIdStr.equalsIgnoreCase(checkProductId)) {
                                                productId = checkProductId;
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                            if (UtilValidate.isEmpty(productId)) {
                                List<GenericValue> contentDataResourceViews = EntityQuery.use(delegator).from("ContentDataResourceView").where("contentId", contentId, "drDataResourceTypeId", "ELECTRONIC_TEXT").cache(true).queryList();
                                for (GenericValue contentDataResourceView : contentDataResourceViews) {
                                    GenericValue ElectronicText = contentDataResourceView.getRelatedOne("ElectronicText", true);
                                    if (UtilValidate.isNotEmpty(ElectronicText)) {
                                        String textData = (String) ElectronicText.get("textData");
                                        if (UtilValidate.isNotEmpty(textData)) {
                                            textData = UrlServletHelper.invalidCharacter(textData);
                                            if (alternativeUrl.matches(textData + ".+$")) {
                                                String productIdStr = null;
                                                productIdStr = alternativeUrl.replace(textData + "-", "");
                                                productIdStr = productIdStr.replace("-p", "");
                                                String checkProductId = (String) productContentInfo.get("productId");
                                                if (productIdStr.equalsIgnoreCase(checkProductId)) {
                                                    productId = checkProductId;
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                
                // look for productCategoryId
                if (alternativeUrl.endsWith("-c")) {
                    List<EntityCondition> productCategoryContentConds = new LinkedList<EntityCondition>();
                    productCategoryContentConds.add(EntityCondition.makeCondition("prodCatContentTypeId", "ALTERNATIVE_URL"));
                    productCategoryContentConds.add(EntityUtil.getFilterByDateExpr());
                    List<GenericValue> productCategoryContentInfos = EntityQuery.use(delegator).from("ProductCategoryContentAndInfo").where(productCategoryContentConds).orderBy("-fromDate").cache(true).queryList();
                    if (UtilValidate.isNotEmpty(productCategoryContentInfos)) {
                        for (GenericValue productCategoryContentInfo : productCategoryContentInfos) {
                            String contentId = (String) productCategoryContentInfo.get("contentId");
                            List<GenericValue> ContentAssocDataResourceViewTos = EntityQuery.use(delegator).from("ContentAssocDataResourceViewTo").where("contentIdStart", contentId, "caContentAssocTypeId", "ALTERNATE_LOCALE", "drDataResourceTypeId", "ELECTRONIC_TEXT").cache(true).queryList();
                            if (UtilValidate.isNotEmpty(ContentAssocDataResourceViewTos)) {
                                for (GenericValue ContentAssocDataResourceViewTo : ContentAssocDataResourceViewTos) {
                                    GenericValue ElectronicText = ContentAssocDataResourceViewTo.getRelatedOne("ElectronicText", true);
                                    if (ElectronicText != null) {
                                        String textData = (String) ElectronicText.get("textData");
                                        if (UtilValidate.isNotEmpty(textData)) {
                                            textData = UrlServletHelper.invalidCharacter(textData);
                                            if (alternativeUrl.matches(textData + ".+$")) {
                                                String productCategoryStr = null;
                                                productCategoryStr = alternativeUrl.replace(textData + "-", "");
                                                productCategoryStr = productCategoryStr.replace("-c", "");
                                                String checkProductCategoryId = (String) productCategoryContentInfo.get("productCategoryId");
                                                if (productCategoryStr.equalsIgnoreCase(checkProductCategoryId)) {
                                                    productCategoryId = checkProductCategoryId;
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            if (UtilValidate.isEmpty(productCategoryId)) {
                                List<GenericValue> contentDataResourceViews = EntityQuery.use(delegator).from("ContentDataResourceView").where("contentId", contentId, "drDataResourceTypeId", "ELECTRONIC_TEXT").cache(true).queryList();
                                for (GenericValue contentDataResourceView : contentDataResourceViews) {
                                    GenericValue ElectronicText = contentDataResourceView.getRelatedOne("ElectronicText", true);
                                    if (ElectronicText != null) {
                                        String textData = (String) ElectronicText.get("textData");
                                        if (UtilValidate.isNotEmpty(textData)) {
                                            textData = UrlServletHelper.invalidCharacter(textData);
                                            if (alternativeUrl.matches(textData + ".+$")) {
                                                String productCategoryStr = null;
                                                productCategoryStr = alternativeUrl.replace(textData + "-", "");
                                                productCategoryStr = productCategoryStr.replace("-c", "");
                                                String checkProductCategoryId = (String) productCategoryContentInfo.get("productCategoryId");
                                                if (productCategoryStr.equalsIgnoreCase(checkProductCategoryId)) {
                                                    productCategoryId = checkProductCategoryId;
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

            } catch (GenericEntityException e) {
                Debug.logWarning("Cannot look for product and product category", module);
            }
            
            // generate forward URL
            StringBuilder urlBuilder = new StringBuilder();
            urlBuilder.append("/" + WebAppUtil.CONTROL_MOUNT_POINT);
            
            if (UtilValidate.isNotEmpty(productId)) {
                try {
                    List<EntityCondition> conds = new LinkedList<EntityCondition>();
                    conds.add(EntityCondition.makeCondition("productId", productId));
                    conds.add(EntityUtil.getFilterByDateExpr());
                    List<GenericValue> productCategoryMembers = EntityQuery.use(delegator).select("productCategoryId").from("ProductCategoryMember").where(conds).orderBy("-fromDate").cache(true).queryList();
                    if (UtilValidate.isNotEmpty(productCategoryMembers)) {
                        GenericValue productCategoryMember = EntityUtil.getFirst(productCategoryMembers);
                        productCategoryId = productCategoryMember.getString("productCategoryId");
                    }
                } catch (GenericEntityException e) {
                    Debug.logError(e, "Cannot find product category for product: " + productId, module);
                }
                urlBuilder.append("/" + PRODUCT_REQUEST);
                
            } else {
                urlBuilder.append("/" + CATEGORY_REQUEST);
            }

            // generate trail belong to a top category
            String topCategoryId = CategoryWorker.getCatalogTopCategory(httpRequest, null);
            List<GenericValue> trailCategories = CategoryWorker.getRelatedCategoriesRet(httpRequest, "trailCategories", topCategoryId, false, false, true);
            List<String> trailCategoryIds = EntityUtil.getFieldListFromEntityList(trailCategories, "productCategoryId", true);
            
            // look for productCategoryId from productId
            if (UtilValidate.isNotEmpty(productId)) {
                try {
                    List<EntityCondition> rolllupConds = new LinkedList<EntityCondition>();
                    rolllupConds.add(EntityCondition.makeCondition("productId", productId));
                    rolllupConds.add(EntityUtil.getFilterByDateExpr());
                    List<GenericValue> productCategoryMembers = EntityQuery.use(delegator).from("ProductCategoryMember").where(rolllupConds).orderBy("-fromDate").cache(true).queryList();
                    for (GenericValue productCategoryMember : productCategoryMembers) {
                        String trailCategoryId = productCategoryMember.getString("productCategoryId");
                        if (trailCategoryIds.contains(trailCategoryId)) {
                            productCategoryId = trailCategoryId;
                            break;
                        }
                    }
                } catch (GenericEntityException e) {
                    Debug.logError(e, "Cannot generate trail from product category", module);
                }
            }

            // generate trail elements from productCategoryId
            if (UtilValidate.isNotEmpty(productCategoryId)) {
                List<String> trailElements = new LinkedList<String>();
                trailElements.add(productCategoryId);
                String parentProductCategoryId = productCategoryId;
                while (UtilValidate.isNotEmpty(parentProductCategoryId)) {
                    // find product category rollup
                    try {
                        List<EntityCondition> rolllupConds = new LinkedList<EntityCondition>();
                        rolllupConds.add(EntityCondition.makeCondition("productCategoryId", parentProductCategoryId));
                        rolllupConds.add(EntityUtil.getFilterByDateExpr());
                        List<GenericValue> productCategoryRollups = EntityQuery.use(delegator).from("ProductCategoryRollup").where(rolllupConds).orderBy("-fromDate").cache(true).queryList();
                        if (UtilValidate.isNotEmpty(productCategoryRollups)) {
                            // add only categories that belong to the top category to trail
                            for (GenericValue productCategoryRollup : productCategoryRollups) {
                                String trailCategoryId = productCategoryRollup.getString("parentProductCategoryId");
                                parentProductCategoryId = trailCategoryId;
                                if (trailCategoryIds.contains(trailCategoryId)) {
                                    trailElements.add(trailCategoryId);
                                    break;
                                }
                            }
                        } else {
                            parentProductCategoryId = null;
                        }
                    } catch (GenericEntityException e) {
                        Debug.logError(e, "Cannot generate trail from product category", module);
                    }
                }
                Collections.reverse(trailElements);
                
                List<String> trail = CategoryWorker.getTrail(httpRequest);
                if (trail == null) {
                    trail = new LinkedList<String>();
                }

                // adjust trail
                String previousCategoryId = null;
                if (trail.size() > 0) {
                    previousCategoryId = trail.get(trail.size() - 1);
                }
                trail = CategoryWorker.adjustTrail(trail, productCategoryId, previousCategoryId);
                
                if (trailElements.size() == 1) {
                    CategoryWorker.setTrail(request, trailElements.get(0), null);
                } else if (trailElements.size() == 2) {
                    CategoryWorker.setTrail(request, trailElements.get(1), trailElements.get(0));
                } else if (trailElements.size() > 2) {
                    if (trail.contains(trailElements.get(0))) {
                        // first category is in the trail, so remove it everything after that and fill it in with the list from the pathInfo
                        int firstElementIndex = trail.indexOf(trailElements.get(0));
                        while (trail.size() > firstElementIndex) {
                            trail.remove(firstElementIndex);
                        }
                        trail.addAll(trailElements);
                    } else {
                        // first category is NOT in the trail, so clear out the trail and use the trailElements list
                        trail.clear();
                        trail.addAll(trailElements);
                    }
                    CategoryWorker.setTrail(request, trail);
                }

                request.setAttribute("productCategoryId", productCategoryId);
                
                if (productId != null) {
                    request.setAttribute("product_id", productId);
                    request.setAttribute("productId", productId);
                }
            }
            
            //Set view query parameters
            UrlServletHelper.setViewQueryParameters(request, urlBuilder);
            if (UtilValidate.isNotEmpty(productId) || UtilValidate.isNotEmpty(productCategoryId) || UtilValidate.isNotEmpty(urlContentId)) {
                Debug.logInfo("[Filtered request]: " + pathInfo + " (" + urlBuilder + ")", module);
                RequestDispatcher dispatch = request.getRequestDispatcher(urlBuilder.toString());
                dispatch.forward(request, response);
                return;
            }
            
            //Check path alias
            UrlServletHelper.checkPathAlias(request, httpResponse, delegator, pathInfo);
        }
        
        // we're done checking; continue on
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {

    }

    public static String makeCategoryUrl(HttpServletRequest request, String previousCategoryId, String productCategoryId, String productId, String viewSize, String viewIndex, String viewSort, String searchString) {
        Delegator delegator = (Delegator) request.getAttribute("delegator");
        try {
            GenericValue productCategory = EntityQuery.use(delegator).from("ProductCategory").where("productCategoryId", productCategoryId).cache().queryOne();
            CategoryContentWrapper wrapper = new CategoryContentWrapper(productCategory, request);
            List<String> trail = CategoryWorker.getTrail(request);
            return makeCategoryUrl(delegator, wrapper, trail, request.getContextPath(), previousCategoryId, productCategoryId, productId, viewSize, viewIndex, viewSort, searchString);
        } catch (GenericEntityException e) {
            Debug.logWarning(e, "Cannot create category's URL for: " + productCategoryId, module);
            return redirectUrl;
        }
    }

    public static String makeCategoryUrl(Delegator delegator, CategoryContentWrapper wrapper, List<String> trail, String contextPath, String previousCategoryId, String productCategoryId, String productId, String viewSize, String viewIndex, String viewSort, String searchString) {
        String url = "";
        StringWrapper alternativeUrl = wrapper.get("ALTERNATIVE_URL", "url");
        
        if (UtilValidate.isNotEmpty(alternativeUrl) && UtilValidate.isNotEmpty(alternativeUrl.toString())) {
            StringBuilder urlBuilder = new StringBuilder();
            urlBuilder.append(contextPath);
            if (urlBuilder.length() == 0 || urlBuilder.charAt(urlBuilder.length() - 1) != '/') {
                urlBuilder.append("/");
            }
            // append alternative URL
            url = UrlServletHelper.invalidCharacter(alternativeUrl.toString());
            urlBuilder.append(url);
            if (UtilValidate.isNotEmpty(productCategoryId)) {
                urlBuilder.append("-");
                urlBuilder.append(productCategoryId);
                urlBuilder.append("-c");
            }
            // append view index
            if (UtilValidate.isNotEmpty(viewIndex)) {
                if (!urlBuilder.toString().endsWith("?") && !urlBuilder.toString().endsWith("&")) {
                    urlBuilder.append("?");
                }
                urlBuilder.append("viewIndex=" + viewIndex + "&");
            }
            // append view size
            if (UtilValidate.isNotEmpty(viewSize)) {
                if (!urlBuilder.toString().endsWith("?") && !urlBuilder.toString().endsWith("&")) {
                    urlBuilder.append("?");
                }
                urlBuilder.append("viewSize=" + viewSize + "&");
            }
            // append view sort
            if (UtilValidate.isNotEmpty(viewSort)) {
                if (!urlBuilder.toString().endsWith("?") && !urlBuilder.toString().endsWith("&")) {
                    urlBuilder.append("?");
                }
                urlBuilder.append("viewSort=" + viewSort + "&");
            }
            // append search string
            if (UtilValidate.isNotEmpty(searchString)) {
                if (!urlBuilder.toString().endsWith("?") && !urlBuilder.toString().endsWith("&")) {
                    urlBuilder.append("?");
                }
                urlBuilder.append("searchString=" + searchString + "&");
            }
            if (urlBuilder.toString().endsWith("&")) {
                return urlBuilder.toString().substring(0, urlBuilder.toString().length()-1);
            }
            
            url = urlBuilder.toString();
        } else {
            if (UtilValidate.isEmpty(trail)) {
                trail = new LinkedList<String>();
            }
            url = CatalogUrlServlet.makeCatalogUrl(contextPath, trail, productId, productCategoryId, previousCategoryId);
        }
        
        return url;
    }
    
    public static String makeProductUrl(HttpServletRequest request, String previousCategoryId, String productCategoryId, String productId) {
        Delegator delegator = (Delegator) request.getAttribute("delegator");
        String url = null;
        try {
            GenericValue product = EntityQuery.use(delegator).from("Product").where("productId", productId).cache().queryOne();
            ProductContentWrapper wrapper = new ProductContentWrapper(product, request);
            List<String> trail = CategoryWorker.getTrail(request);
            url = makeProductUrl(wrapper, trail, request.getContextPath(), previousCategoryId, productCategoryId, productId);
        } catch (GenericEntityException e) {
            Debug.logWarning(e, "Cannot create product's URL for: " + productId, module);
            return redirectUrl;
        }
        return url;
    }

    public static String makeProductUrl(ProductContentWrapper wrapper, List<String> trail, String contextPath, String previousCategoryId, String productCategoryId, String productId) {
        String url = "";
        StringWrapper alternativeUrl = wrapper.get("ALTERNATIVE_URL", "url");
        if (UtilValidate.isNotEmpty(alternativeUrl) && UtilValidate.isNotEmpty(alternativeUrl.toString())) {
            StringBuilder urlBuilder = new StringBuilder();
            urlBuilder.append(contextPath);
            if (urlBuilder.length() == 0 || urlBuilder.charAt(urlBuilder.length() - 1) != '/') {
                urlBuilder.append("/");
            }
            // append alternative URL
            url = UrlServletHelper.invalidCharacter(alternativeUrl.toString());
            urlBuilder.append(url);
            if (UtilValidate.isNotEmpty(productId)) {
                urlBuilder.append("-");
                urlBuilder.append(productId);
                urlBuilder.append("-p");
            }
            url = urlBuilder.toString();
        } else {
            if (UtilValidate.isEmpty(trail)) {
                trail = new LinkedList<String>();
            }
            url = CatalogUrlServlet.makeCatalogUrl(contextPath, trail, productId, productCategoryId, previousCategoryId);
        }
        return url;
    }
}
