package com.firefly.server.http2.router.impl;

import com.firefly.server.http2.router.Matcher;
import com.firefly.server.http2.router.Router;

import java.util.*;
import java.util.regex.Pattern;

/**
 * @author Pengtao Qiu
 */
abstract public class AbstractRegexMatcher implements Matcher {

    protected Map<RegexRule, Set<Router>> regexMap;

    protected static class RegexRule {
        final String rule;
        final Pattern pattern;

        protected RegexRule(String rule) {
            this.rule = rule;
            pattern = Pattern.compile(rule);
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            RegexRule regexRule = (RegexRule) o;
            return Objects.equals(rule, regexRule.rule);
        }

        @Override
        public int hashCode() {
            return Objects.hash(rule);
        }
    }

    protected Map<RegexRule, Set<Router>> regexMap() {
        if (regexMap == null) {
            regexMap = new HashMap<>();
        }
        return regexMap;
    }

    @Override
    public void add(String rule, Router router) {
        regexMap().computeIfAbsent(new RegexRule(rule), k -> new HashSet<>()).add(router);
    }

    @Override
    public MatchResult match(String value) {
        if (regexMap == null) {
            return null;
        }

        Set<Router> routers = new HashSet<>();
        Map<Router, Map<String, String>> parameters = new HashMap<>();

        regexMap.entrySet()
                .forEach(e -> {
                    java.util.regex.Matcher m = e.getKey().pattern.matcher(value);
                    if (m.matches()) {
                        routers.addAll(e.getValue());
                        m = e.getKey().pattern.matcher(value);

                        Map<String, String> param = new HashMap<>();
                        while (m.find()) {
                            for (int i = 1; i <= m.groupCount(); i++) {
                                param.put("group" + i, m.group(i));
                            }
                        }
                        if (!param.isEmpty()) {
                            e.getValue().forEach(router -> parameters.put(router, param));
                        }
                    }
                });
        if (routers.isEmpty()) {
            return null;
        } else {
            return new MatchResult(routers, parameters, getMatchType());
        }
    }
}

@@ -1557,59 +1557,39 @@
 Map.
-entrySet()%0A                .forEach(e -%3E %7B%0A        
+forEach((rule, routerSet) -%3E %7B%0A
     
@@ -1620,34 +1620,28 @@
 Matcher m = 
-e.getKey()
+rule
 .pattern.mat
@@ -1661,32 +1661,24 @@
             
-     
-   
 if (m.matche
@@ -1700,24 +1700,16 @@
         
-        
 routers.
@@ -1715,28 +1715,25 @@
 .addAll(
-e.getValue()
+routerSet
 );%0A     
@@ -1747,30 +1747,16 @@
     
- 
-       m = e.getKey()
+m = rule
 .pat
@@ -1777,24 +1777,16 @@
 alue);%0A%0A
-        
         
@@ -1854,24 +1854,16 @@
         
-        
 while (m
@@ -1893,24 +1893,16 @@
         
-      
-  
 for (int
@@ -1961,24 +1961,16 @@
         
-        
 param.pu
@@ -2017,34 +2017,18 @@
         
-    
-    %7D%0A        
+%7D%0A
         
@@ -2049,32 +2049,24 @@
             
- 
-       
 if (!param.i
@@ -2101,28 +2101,17 @@
     
-        e.getValue()
+routerSet
 .for
@@ -2177,38 +2177,8 @@
     
-        %7D%0A                    
 %7D%0A  
@@ -2175,32 +2175,38 @@
       %7D%0A        
+    %7D%0A
         %7D);%0A    

clean up codes