package org.jenkinsci.plugins.lucene.search.databackend;

import hudson.Extension;
import hudson.model.Item;
import hudson.model.Run;
import hudson.search.SearchResult;
import hudson.search.SuggestedItem;
import jenkins.model.Jenkins;
import org.apache.log4j.Logger;
import org.jenkinsci.plugins.lucene.search.FreeTextSearchItemImplementation;
import org.jenkinsci.plugins.lucene.search.SearchResultImpl;
import org.jenkinsci.plugins.lucene.search.config.SearchBackendConfiguration;

import javax.inject.Inject;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Extension
public class SearchBackendManager {
    private static final Logger LOG = Logger.getLogger(SearchBackendManager.class);

    private transient SearchBackend<?> instance;
    private transient List<SearchFieldDefinition> cachedFieldDefinitions;

    @Inject
    private transient SearchBackendConfiguration backendConfig;

    private synchronized SearchBackend<?> getBackend() {
        if (instance == null) {
            instance = LuceneSearchBackend.create(backendConfig.getConfig());
        }
        return instance;
    }

    public synchronized void reconfigure(final Map<String, Object> config) throws IOException {
        if (instance != null) {
            instance.close();
            instance = instance.reconfigure(config);
        } else {
            instance = LuceneSearchBackend.create(backendConfig.getConfig());
        }
    }

    public List<FreeTextSearchItemImplementation> getHits(String query, boolean searchNext) {
        List<FreeTextSearchItemImplementation> hits = getBackend().getHits(query, searchNext);
        if (backendConfig.isUseSecurity()) {
            Jenkins jenkins = Jenkins.getInstance();
            Iterator<FreeTextSearchItemImplementation> iter = hits.iterator();
            while (iter.hasNext()) {
                FreeTextSearchItemImplementation searchItem = iter.next();
                Item item = jenkins.getItem(searchItem.getProjectName());
                if (item == null) {
                    iter.remove();
                }
            }
        }
        return hits;
    }

    public SearchResult getSuggestedItems(String query) {
        SearchResultImpl result = new SearchResultImpl();
        for (FreeTextSearchItemImplementation item : getHits(query, false)) {
            result.add(new SuggestedItem(item));
        }
        return result;
    }

    public void removeBuild(Run<?, ?> run) throws IOException {
        getBackend().removeBuild(run);
    }

    public void deleteJob(String jobName) throws IOException {
        getBackend().deleteJob(jobName);
    }


    public void storeBuild(Run<?, ?> run) throws IOException {
        getBackend().storeBuild(run, null);
    }

    public void rebuildDatabase(ManagerProgress progress, int maxWorkers, Set<String> jobs, boolean overwrite) {
        try {
            getBackend().rebuildDatabase(progress, maxWorkers);
        } catch (Exception e) {
            progress.completedWithErrors(e);
            LOG.error("Failed rebuilding search database", e);
        } finally {
            progress.setFinished();
        }
    }
}
@@ -194,24 +194,103 @@
 gestedItem;%0A
+%0Aimport java.io.IOException;%0Aimport java.util.*;%0A%0Aimport javax.inject.Inject;%0A%0A
 import jenki
@@ -307,16 +307,17 @@
 enkins;%0A
+%0A
 import o
@@ -561,159 +561,8 @@
 n;%0A%0A
-import javax.inject.Inject;%0Aimport java.io.IOException;%0Aimport java.util.Iterator;%0Aimport java.util.List;%0Aimport java.util.Map;%0Aimport java.util.Set;%0A%0A
 @Ext
@@ -2390,32 +2390,161 @@
  result;%0A    %7D%0A%0A
+    public void clean(ManagerProgress progress) %7B%0A        progress.setMax(1);%0A        getBackend().cleanAllJob(progress);%0A    %7D%0A%0A
     public void 
@@ -2583,32 +2583,32 @@
 s IOException %7B%0A
-
         getBacke
@@ -2851,14 +2851,8 @@
 (run
-, null
 );%0A 
@@ -2980,24 +2980,24 @@
       try %7B%0A
-
             
@@ -3045,16 +3045,33 @@
 xWorkers
+, jobs, overwrite
 );%0A     

modify SearchBackendManager