package org.opencommercesearch;

/*
* Licensed to OpenCommerceSearch under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. OpenCommerceSearch 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.
*/

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.opencommercesearch.Facet.Filter;

import com.google.common.collect.Lists;

public class CategoryGraphBuilder {

    private static final String CATEGORY_PATH = "categoryPath";
    
    private CategoryGraph parentNode = new CategoryGraph();    
    
    public CategoryGraph getParentNode() {
        return parentNode;
    }

    public void setParentVO(CategoryGraph parentNode) {
        this.parentNode = parentNode;
    }

    public CategoryGraphBuilder() {
        List<CategoryGraph> childList = Lists.newArrayList();
        parentNode.setCategoryGraphNodes(childList);
    }
    
    public List<CategoryGraph> getCategoryGraphList() {
        return parentNode.getCategoryGraphNodes();
    }
    
    public void addPath(Filter filter){
        String filterPath = Utils.findFilterExpressionByName(filter.getPath(), CATEGORY_PATH);
        if(filterPath != null) {
            String[] pathArray = filterPath.split("\\"+SearchConstants.CATEGORY_SEPARATOR);
            parentNode.setId(pathArray[0]);
            recursiveAdd(filter, Arrays.copyOfRange(pathArray, 1 ,pathArray.length), parentNode);
        }  
    }

    private void recursiveAdd(Filter filter, String[] pathArray, CategoryGraph parentNode) {
        
        if(pathArray == null || pathArray.length == 0){
            return;
        }
        
        if(pathArray.length == 1){
            createNewNode(filter, parentNode);
        } else {
            
            String currentId = pathArray[0];
            CategoryGraph node = search(currentId, parentNode);
            
            if (node == null) {
                node = new CategoryGraph();
                List<CategoryGraph> childList = Lists.newArrayList();
                node.setCategoryGraphNodes(childList);
                node.setId(currentId);
                parentNode.getCategoryGraphNodes().add(node);
            }
            
            recursiveAdd(filter, Arrays.copyOfRange(pathArray, 1, pathArray.length), node);
        }

    }
    
    private void createNewNode(Filter filter, CategoryGraph parentNode) {
        
        CategoryGraph node = search(filter.getName(), parentNode);
        List<CategoryGraph> parentChildList = parentNode.getCategoryGraphNodes();
        
        if (node == null) {                
            node = new CategoryGraph();
            List<CategoryGraph> childList = Lists.newArrayList();
            node.setCategoryGraphNodes(childList);
            parentChildList.add(node);
        }
        
        node.setCount((int) filter.getCount());
        node.setPath(filter.getPath());
        String name = filter.getName();
        int lastDotIndex = name.lastIndexOf('.');
        if (lastDotIndex != -1) {
            name = name.substring(lastDotIndex+1);
        }
        node.setId(name);
        Collections.sort(parentChildList);
    }
    
    public CategoryGraph search(String id, CategoryGraph graphNode){
        
        if (id.equals(graphNode.getId())) {
            return graphNode;
        }
        
        CategoryGraph result = null;
        for (CategoryGraph childFacet : graphNode.getCategoryGraphNodes()) {
            result = search(id, childFacet);
            if (result != null) {
                break;
            }
        }
        return result;
    }
    
}

@@ -884,16 +884,60 @@
 .List;%0A%0A
+import org.apache.commons.lang.StringUtils;%0A
 import o
@@ -1852,30 +1852,38 @@
 y = 
-filterPath.split(%22%5C%5C%22+
+StringUtils.split(filterPath, 
 Sear
@@ -1996,58 +1996,20 @@
 er, 
-Arrays.copyOfRange(pathArray, 1 ,pathArray.length)
+pathArray, 1
 , pa
@@ -2102,16 +2102,32 @@
 thArray,
+ int arrayIndex,
  Categor
@@ -2264,26 +2264,153 @@
    i
-f(pathArray.length
+nt currentOffset = pathArray.length - arrayIndex;%0A        if(currentOffset %3C 1) %7B%0A            return;%0A        %7D%0A        %0A        if(currentOffset
  == 
@@ -2531,17 +2531,26 @@
 thArray%5B
-0
+arrayIndex
 %5D;%0A     
@@ -2987,58 +2987,31 @@
 er, 
-Arrays.copyOfRange(pathArray, 1, pathArray.length)
+pathArray, arrayIndex+1
 , no

add performance of the categoryGraphBuilder