package org.codelibs.elasticsearch.qrcache.filter;

import org.codelibs.elasticsearch.qrcache.cache.QueryResultCache;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.action.search.SearchAction;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.action.support.ActionFilter;
import org.elasticsearch.action.support.ActionFilterChain;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;

public class QueryResultCacheFilter implements ActionFilter {
    private int order;

    private QueryResultCache queryResultCache;

    private ThreadLocal<SearchType> currentSearchType = new ThreadLocal<>();

    @Inject
    public QueryResultCacheFilter(final Settings settings,
            final QueryResultCache queryResultCache) {
        this.queryResultCache = queryResultCache;

        order = settings.getAsInt("indices.qrc.filter.order", 5);
    }

    @Override
    public int order() {
        return order;
    }

    @Override
    public void apply(final String action, final ActionRequest request,
            final ActionListener listener, final ActionFilterChain chain) {
        if (!SearchAction.INSTANCE.name().equals(action)) {
            chain.proceed(action, request, listener);
            return;
        }

        final SearchRequest searchRequest = (SearchRequest) request;
        final SearchType searchType = currentSearchType.get();
        if (searchType == null) {
            try {
                currentSearchType.set(searchRequest.searchType());
                chain.proceed(action, request, listener);
            } finally {
                currentSearchType.remove();
            }
        } else if (queryResultCache.canCache(searchRequest)) {
            final ActionListener cacheListener = queryResultCache.execute(
                    searchRequest, listener, chain);
            if (cacheListener != null) {
                chain.proceed(action, request, cacheListener);
            }
        } else {
            chain.proceed(action, request, listener);
        }

    }

    @Override
    public void apply(final String action, final ActionResponse response,
            final ActionListener listener, final ActionFilterChain chain) {
        chain.proceed(action, response, listener);
    }

}

@@ -365,59 +365,8 @@
 st;%0A
-import org.elasticsearch.action.search.SearchType;%0A
 impo
@@ -651,143 +651,158 @@
 ate 
-int order;%0A%0A    private QueryResultCache queryResultCache;%0A%0A    private ThreadLocal%3CSearchType%3E currentSearchType = new ThreadLocal%3C%3E()
+static final String SEARCH_REQUEST_INVOKED = %22filter.codelibs.qrcache.Invoked%22;%0A%0A    private int order;%0A%0A    private QueryResultCache queryResultCache
 ;%0A%0A 
@@ -1166,32 +1166,74 @@
 l String action,
+%0A            @SuppressWarnings(%22rawtypes%22)
  final ActionReq
@@ -1249,32 +1249,62 @@
 est,%0A           
+ @SuppressWarnings(%22rawtypes%22)
  final ActionLis
@@ -1310,32 +1310,44 @@
 stener listener,
+%0A           
  final ActionFil
@@ -1596,379 +1596,259 @@
 nal 
-SearchType searchType = currentSearchType.get();%0A        if (searchType == null) %7B%0A            try %7B%0A                currentSearchType.set(searchRequest.searchType());%0A                chain.proceed(action, request, listener);%0A            %7D finally %7B%0A                currentSearchType.remove();%0A            %7D%0A        %7D else if (queryResultCache.canCache(searchRequest)) %7B%0A
+Boolean invoked = searchRequest.getHeader(SEARCH_REQUEST_INVOKED);%0A        if (invoked != null && invoked.booleanValue()) %7B%0A            if (queryResultCache.canCache(searchRequest)) %7B%0A                @SuppressWarnings(%7B %22rawtypes%22, %22unchecked%22 %7D)%0A    
     
@@ -1912,17 +1912,8 @@
 ache
-.execute(
 %0A   
@@ -1929,16 +1929,29 @@
         
+    .execute(
 searchRe
@@ -1983,24 +1983,28 @@
             
+    
 if (cacheLis
@@ -2016,24 +2016,28 @@
  != null) %7B%0A
+    
             
@@ -2099,18 +2099,26 @@
         
-%7D%0A
+    %7D%0A    
         
@@ -2126,16 +2126,180 @@
  else %7B%0A
+                chain.proceed(action, request, listener);%0A            %7D%0A        %7D else %7B%0A            searchRequest.putHeader(SEARCH_REQUEST_INVOKED, Boolean.TRUE);%0A
         
@@ -2350,25 +2350,24 @@
 ;%0A        %7D%0A
-%0A
     %7D%0A%0A    @
@@ -2452,32 +2452,62 @@
 nse,%0A           
+ @SuppressWarnings(%22rawtypes%22)
  final ActionLis

fix #8