package com.wizzardo.http;

import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;

/**
 * Created by wizzardo on 19.01.15.
 */
public class ChainUrlMapping<T> extends UrlMapping<Set<T>> {

    public ChainUrlMapping<T> add(String url, T t) {
        UrlMapping<Set<T>> tree = this;
        String[] parts = url.split("/");

        int i;
        for (i = 0; i < parts.length && tree != null; i++) {
            String part = parts[i];
            if (part.isEmpty())
                continue;

            if (part.contains("*"))
                part = part.replace("*", ".*");
            else if (part.contains("$"))
                part = convertRegexpVariables(part);

            UrlMapping<Set<T>> next = tree.find(part);
            if (next != null && next.value != null && i == parts.length - 1)
                next.value.add(t);

            if (next == null && i == parts.length - 1)
                addToAll(part, tree, t);
            tree = next;
        }


        Set<T> set = new LinkedHashSet<>();
        tree = this;
        for (i = 0; i < parts.length; i++) {
            String part = parts[i];
            if (part.isEmpty())
                continue;

            if (part.contains("*"))
                part = part.replace("*", ".*");
            else if (part.contains("$"))
                part = convertRegexpVariables(part);

            UrlMapping<Set<T>> next = tree.find(part);
            if (next != null) {
                if (next.value != null)
                    set.addAll(next.value);
                tree = next;
            } else
                break;
        }
        set.add(t);
        append(url, set);

        return this;
    }

    private void addToAll(UrlMapping<Set<T>> tree, T t) {
        if (tree.value != null)
            tree.value.add(t);

        for (Map.Entry<String, UrlMapping<Set<T>>> entry : tree.mapping.entrySet())
            addToAll(entry.getValue(), t);

        for (Map.Entry<String, UrlMappingMatcher<Set<T>>> entry : tree.regexpMapping.entrySet())
            addToAll(entry.getValue(), t);
    }

    private void addToAll(String pattern, UrlMapping<Set<T>> tree, T t) {
        Pattern p = Pattern.compile(pattern);

        for (Map.Entry<String, UrlMapping<Set<T>>> entry : tree.mapping.entrySet())
            if (p.matcher(entry.getKey()).matches())
                addToAll(entry.getValue(), t);

        for (Map.Entry<String, UrlMappingMatcher<Set<T>>> entry : tree.regexpMapping.entrySet())
            if (p.matcher(entry.getKey()).matches())
                addToAll(entry.getValue(), t);
    }
}

@@ -1418,39 +1418,57 @@
         
-UrlMapping%3CSet%3CT%3E%3E next
+addAll(part, tree, set);%0A            tree
  = tree.
@@ -1499,23 +1499,21 @@
 if (
-next !
+tree =
 = null)
- %7B
 %0A   
@@ -1529,31 +1529,14 @@
     
-if (next.value != null)
+break;
 %0A   
@@ -1536,28 +1536,26 @@
 ak;%0A        
-    
+%7D%0A
         set.
@@ -1561,41 +1561,48 @@
 .add
-All(next.value);%0A        
+(t);%0A        append(url, set);%0A%0A
         
 tree
@@ -1601,81 +1601,225 @@
     
-t
 re
-e = next
+turn this
 ;%0A    
+%7D%0A%0A
     
-    %7D else%0A                break;%0A        %7D%0A
+private void addAll(String part, UrlMapping%3CSet%3CT%3E%3E tree, Set%3CT%3E set) %7B%0A        UrlMapping%3CSet%3CT%3E%3E values = tree.mapping.get(part);%0A        if (values != null && values.value != null)%0A 
         
 set.
@@ -1814,36 +1814,54 @@
         
+   
 set.add
-(t
+All(values.value
 );%0A
+%0A
         
 append(u
@@ -1856,47 +1856,237 @@
     
-append(url, set);%0A%0A        return this;
+for (Map.Entry%3CString, UrlMappingMatcher%3CSet%3CT%3E%3E%3E entry : regexpMapping.entrySet()) %7B%0A            if (entry.getValue().matches(part) && entry.getValue().value != null)%0A                set.addAll(entry.getValue().value);%0A        %7D
 %0A   

improve filters