package org.wikipedia.search;

import org.wikipedia.ApiTask;
import org.wikipedia.PageTitle;
import org.wikipedia.Site;
import org.wikipedia.WikipediaApp;
import org.mediawiki.api.json.Api;
import org.mediawiki.api.json.ApiException;
import org.mediawiki.api.json.ApiResult;
import org.mediawiki.api.json.RequestBuilder;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.Context;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

public class SearchArticlesTask extends ApiTask<List<PageTitle>> {
    private final String prefix;
    private final Site site;
    private final WikipediaApp app;

    public SearchArticlesTask(Context context, Api api, Site site, String prefix) {
        super(HIGH_CONCURRENCY, api);
        this.prefix = prefix;
        this.site = site;
        this.app = (WikipediaApp)context.getApplicationContext();
    }

    @Override
    public RequestBuilder buildRequest(Api api) {
        return api.action("query")
                .param("generator", "prefixsearch")
                .param("gpssearch", prefix)
                .param("gpsnamespace", "0")
                .param("gpslimit", "12")
                .param("prop", "pageimages")
                .param("piprop", "thumbnail")
                .param("pithumbsize", Integer.toString(WikipediaApp.PREFERRED_THUMB_SIZE_SEARCH))
                .param("pilimit", "12");
    }

    @Override
    public List<PageTitle> processResult(final ApiResult result) throws Throwable {
        ArrayList<PageTitle> pageTitles = new ArrayList<PageTitle>();
        JSONObject data = null;
        try {
            data = result.asObject();
        } catch (ApiException e) {
            if (e.getCause() instanceof JSONException) {
                // the only reason for a JSONException is if the response is an empty array.
                return pageTitles;
            } else {
                throw new RuntimeException(e);
            }
        }
        JSONObject query = data.optJSONObject("query");
        JSONObject pages = query.getJSONObject("pages");

        Iterator<String> keys = pages.keys();
        while (keys.hasNext()) {
            String key = keys.next();
            JSONObject page = pages.getJSONObject(key);
            String thumbUrl = null;
            if (page.has("thumbnail")) {
                thumbUrl = page.getJSONObject("thumbnail").getString("source");
            }
            pageTitles.add(new PageTitle(page.getString("title"), site, thumbUrl));
        }

        Collections.sort(pageTitles, new Comparator<PageTitle>() {
            @Override
            public int compare(PageTitle pageTitle, PageTitle pageTitle2) {
                return pageTitle.getDisplayText().compareTo(pageTitle2.getDisplayText());
            }
        });

        return pageTitles;
    }
}

@@ -314,16 +314,43 @@
 uilder;%0A
+import org.json.JSONArray;%0A
 import o
@@ -464,94 +464,8 @@
 st;%0A
-import java.util.Collections;%0Aimport java.util.Comparator;%0Aimport java.util.Iterator;%0A
 impo
@@ -609,24 +609,25 @@
  Site site;%0A
+%0A
     private 
@@ -630,30 +630,56 @@
 ate 
-final WikipediaApp app
+static final String NUM_RESULTS_PER_QUERY = %2212%22
 ;%0A%0A 
@@ -859,74 +859,8 @@
 te;%0A
-        this.app = (WikipediaApp)context.getApplicationContext();%0A
     
@@ -1136,20 +1136,37 @@
 limit%22, 
-%2212%22
+NUM_RESULTS_PER_QUERY
 )%0A      
@@ -1382,20 +1382,184 @@
 limit%22, 
-%2212%22
+NUM_RESULTS_PER_QUERY)%0A                .param(%22list%22, %22prefixsearch%22)%0A                .param(%22pssearch%22, prefix)%0A                .param(%22pslimit%22, NUM_RESULTS_PER_QUERY
 );%0A    %7D
@@ -1751,23 +1751,16 @@
 ect data
- = null
 ;%0A      
@@ -2108,32 +2108,586 @@
      %7D%0A        %7D
+%0A%0A        /*%0A        So here's what we're doing here:%0A        We're requesting two sets of results with our API query. They both contain the same titles,%0A        but in different orders.  The results given by %22list=prefixsearch%22 give us the results in%0A        the correct order, but with no thumbnails.  The results given by %22generator=prefixsearch%22%0A        give the results in the wrong order, but with thumbnails!  So, all we have to do is use the%0A        first list, and correlate the pageids with the second list to extract the thumbnails.%0A        */
 %0A        JSONObj
@@ -2784,25 +2784,24 @@
 ages%22);%0A
-%0A
         
 Iterator
@@ -2796,54 +2796,78 @@
     
-Iterator%3CString%3E keys = pages.keys(
+JSONArray prefixsearch = query.getJSONArray(%22prefixsearch%22
 );%0A
+%0A
         
 whil
@@ -2866,29 +2866,54 @@
     
-while (keys.hasNext()
+for (int i = 0; i %3C prefixsearch.length(); i++
 ) %7B%0A
@@ -2935,25 +2935,23 @@
 ing 
-key = keys.next()
+thumbUrl = null
 ;%0A  
@@ -2975,20 +2975,27 @@
 ect 
-page = pages
+item = prefixsearch
 .get
@@ -3009,11 +3009,9 @@
 ect(
-key
+i
 );%0A 
@@ -3032,97 +3032,215 @@
 ing 
-thumbUrl = null;%0A            if (page.has(%22thumbnail%22)) %7B%0A                thumbUrl = page
+pageid = item.getString(%22pageid%22);%0A            if (pages.has(pageid) && pages.getJSONObject(pageid).has(%22thumbnail%22)) %7B%0A                thumbUrl = pages.getJSONObject(pageid)%0A                                
 .get
@@ -3339,20 +3339,20 @@
 geTitle(
-page
+item
 .getStri
@@ -3397,290 +3397,8 @@
  %7D%0A%0A
-        Collections.sort(pageTitles, new Comparator%3CPageTitle%3E() %7B%0A            @Override%0A            public int compare(PageTitle pageTitle, PageTitle pageTitle2) %7B%0A                return pageTitle.getDisplayText().compareTo(pageTitle2.getDisplayText());%0A            %7D%0A        %7D);%0A%0A
     

Update prefix search query to be consistent with Mobile Web.