package de.tblsoft.search.pipeline.filter;

import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import de.tblsoft.search.pipeline.PipelineContainer;
import de.tblsoft.search.query.SearchQuery;
import de.tblsoft.search.response.Document;
import de.tblsoft.search.response.SearchResult;
import de.tblsoft.search.text.TextUtils;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * Created by tbl on 9.12.17.
 */
public class SearchIntentLocationFilter extends AbstractFilter {


    private static Set<String> locationBlacklist = new HashSet<>();
    static{
        locationBlacklist.add("thomas");

    }

    @Override
    public PipelineContainer filter(PipelineContainer pipelineContainer) {
        SearchResult locationLookup = pipelineContainer.getSearchResult("locationLookup");
        SearchQuery searchQuery = pipelineContainer.getSearchQuery();
        if(locationLookup == null) {
            return pipelineContainer;
        }
        String highlightedLocationName = locationLookup.getDocuments().stream().findFirst().map(f -> f.getFieldValue("highlight.name")).orElse(null);

        List<String> normalizedLocationNames = Collections.emptyList();
        if(highlightedLocationName != null) {
            normalizedLocationNames = getHighlightedValues(highlightedLocationName).
                    stream().
                    map(SearchIntentLocationFilter::normalizeToken).
                    collect(Collectors.toList());
        }




        List<String> locationTokens = new ArrayList<>();
        List<String> otherTokens = new ArrayList<>();
        for(String token :Splitter.on(" ").split(searchQuery.getQ())) {
            String normalizedToken = normalizeToken(token);
            if(TextUtils.isGermanPostalCode(token)) {
                otherTokens.add(token);
            } else if(locationBlacklist.contains(token)) {
                otherTokens.add(token);
            } else if(normalizedLocationNames.contains(normalizedToken)) {
                locationTokens.add(token);
            } else {
                otherTokens.add(token);
            }
        }

        SearchResult locationSearchIntent = new SearchResult();
        locationSearchIntent.setStatusCode(200);
        locationSearchIntent.setStatusMessage("OK");
        locationSearchIntent.setTotal(1L);


        Document document = new Document();
        String location = Joiner.on(" ").join(locationTokens);
        String other = Joiner.on(" ").join(otherTokens);

        document.getDocument().put("location", location);
        document.getDocument().put("other", other);
        locationSearchIntent.addDocument(document);

        pipelineContainer.putSearchResult("search-intent",locationSearchIntent);
        return pipelineContainer;
    }




    private static String normalizeToken(String token) {
        token = token.toLowerCase();
        token = TextUtils.replaceGermanUmlaut(token);
        return token;
    }



    private static List<String> getHighlightedValues(String str) {
        if(str==null) {
            return Collections.emptyList();
        }
        Pattern TAG_REGEX = Pattern.compile(".*?<em>(.*?)</em>.*?");
        final List<String> tagValues = new ArrayList<>();
        final Matcher matcher = TAG_REGEX.matcher(str);
        while (matcher.find()) {
            tagValues.add(matcher.group(1));
        }
        return tagValues;
    }

}

@@ -697,24 +697,410 @@
 %22);%0A%0A    %7D%0A%0A
+    private Set%3CString%3E normalizeLocationNames(String highlightedLocationName) %7B%0A        if(highlightedLocationName == null) %7B%0A            return Collections.emptySet();%0A        %7D%0A%0A        return getHighlightedValues(highlightedLocationName).%0A                stream().%0A                map(SearchIntentLocationFilter::normalizeToken).%0A                collect(Collectors.toSet());%0A    %7D%0A%0A
     @Overrid
@@ -1422,24 +1422,26 @@
       %7D%0A
+%0A%0A
         
 String h
@@ -1436,159 +1436,76 @@
     
-String highlightedLocationName = locationLookup.getDocuments().stream().findFirst().map(f -%3E f.getFieldValue(%22highlight.name%22)).orElse(null)
+int relevantDocuments = 2;%0A        int currentDocument = 0
 ;%0A
-%0A
         
 List
@@ -1492,35 +1492,34 @@
 nt = 0;%0A        
-Lis
+Se
 t%3CString%3E normal
@@ -1542,309 +1542,389 @@
 s = 
-Collections.emptyList();%0A        if(highlightedLocationName != null) %7B%0A            normalizedLocationNames = getHighlightedValues(highlightedLocationName).%0A                    stream().%0A                    map(SearchIntentLocationFilter::normalizeToken).%0A                    collect(Collectors.toList(
+new HashSet%3C%3E();%0A        for(Document document : locationLookup.getDocuments()) %7B%0A            if(currentDocument %3E= relevantDocuments) %7B%0A                break;%0A            %7D%0A            currentDocument++;%0A            String highlightedLocationName = document.getFieldValue(%22highlight.name%22);%0A            normalizedLocationNames.addAll(normalizeLocationNames(highlightedLocationName
 ));%0A

implement use case with more than one city token