/*******************************************************************************
 * 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.IOException;
import java.util.Collections;
import java.util.List;

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

import javolution.util.FastList;

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

public class CatalogUrlFilter extends ContextFilter {

    public final static String module = CatalogUrlFilter.class.getName();
    
    public static final String CONTROL_MOUNT_POINT = "control";
    public static final String PRODUCT_REQUEST = "product";
    public static final String CATEGORY_REQUEST = "category";
    
    protected static String defaultLocaleString = null;
    protected static String redirectUrl = null;
    
    @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");
        
        //Get ServletContext
        ServletContext servletContext = config.getServletContext();
        
        //Set request attribute and session
        UrlServletHelper.setRequestAttributes(request, delegator, servletContext);
        
        // 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 = FastList.newInstance();
                    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 (UtilValidate.isNotEmpty(ElectronicText)) {
                                        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 = FastList.newInstance();
                    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 (UtilValidate.isNotEmpty(ElectronicText)) {
                                        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 (UtilValidate.isNotEmpty(ElectronicText)) {
                                        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("/" + CONTROL_MOUNT_POINT);
            
            if (UtilValidate.isNotEmpty(productId)) {
                try {
                    List<EntityCondition> conds = FastList.newInstance();
                    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 = FastList.newInstance();
                    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 = FastList.newInstance();
                trailElements.add(productCategoryId);
                String parentProductCategoryId = productCategoryId;
                while (UtilValidate.isNotEmpty(parentProductCategoryId)) {
                    // find product category rollup
                    try {
                        List<EntityCondition> rolllupConds = FastList.newInstance();
                        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 = FastList.newInstance();
                }

                // 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);
    }
    
    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");
        
        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 = FastList.newInstance();
            }
            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(delegator, 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(Delegator delegator, ProductContentWrapper wrapper, List<String> trail, String contextPath, String previousCategoryId, String productCategoryId, String productId) {
        String url = "";
        StringWrapper alternativeUrl = wrapper.get("ALTERNATIVE_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 = FastList.newInstance();
            }
            url = CatalogUrlServlet.makeCatalogUrl(contextPath, trail, productId, productCategoryId, previousCategoryId);
        }
        return url;
    }
}
