//
//  SearchHelper.java
//  blogwt
//
//  Created by William Shakour (billy1380) on 20 Aug 2015.
//  Copyright © 2015 WillShex Limited. All rights reserved.
//
package com.willshex.blogwt.server.helper;

import com.google.appengine.api.search.Document;
import com.google.appengine.api.search.Index;
import com.google.appengine.api.search.IndexSpec;
import com.google.appengine.api.search.PutException;
import com.google.appengine.api.search.SearchService;
import com.google.appengine.api.search.SearchServiceFactory;
import com.google.appengine.api.search.StatusCode;
import com.google.appengine.api.taskqueue.Queue;
import com.google.appengine.api.taskqueue.QueueFactory;
import com.google.appengine.api.taskqueue.TaskOptions;
import com.google.appengine.api.taskqueue.TaskOptions.Method;
import com.google.appengine.api.taskqueue.TransientFailureException;
import com.googlecode.objectify.cmd.Query;

/**
 * @author William Shakour (billy1380)
 *
 */
public class SearchHelper {

	public static final String ENTITY_NAME_KEY = "name";
	public static final String ENTITY_ID_KEY = "id";

	private final static String ALL_INDEX_NAME = "all";
	public static final int SHORT_SEARCH_LIMIT = 3;
	private static final String INDEX_SEARCH_URL = "/searchindexer";
	private static SearchService searchService;

	public static void indexDocument (Document document) {
		if (document != null) {
			indexDocument(document, 0);
		}
	}

	private static void indexDocument (Document document, int count) {
		try {
			getIndex().put(document);
		} catch (PutException e) {
			if (StatusCode.TRANSIENT_ERROR
					.equals(e.getOperationResult().getCode())) {
				if (count < 2) {
					indexDocument(document, count++);
				}
			}
		}
	}

	private static SearchService ensureSearchService () {
		if (searchService == null) {
			searchService = SearchServiceFactory.getSearchService();
		}

		return searchService;
	}

	public static void deleteSearch (String documentId) {
		getIndex().delete(documentId);
	}

	public static Index getIndex () {
		return ensureSearchService().getIndex(
				IndexSpec.newBuilder().setName(ALL_INDEX_NAME).build());
	}

	public static <T> Query<T> addStartsWith (String field, String text,
			Query<T> query) {
		return query.filter(field + " >=", text).filter(field + " <",
				text + "\ufffd");
	}

	/**
	 * @param name
	 * @param id
	 */
	public static void queueToIndex (String name, Long id) {
		Queue queue = QueueFactory.getDefaultQueue();

		TaskOptions options = TaskOptions.Builder.withMethod(Method.POST)
				.url(INDEX_SEARCH_URL).param(ENTITY_NAME_KEY, name)
				.param(ENTITY_ID_KEY, id.toString());

		try {
			queue.add(options);
		} catch (TransientFailureException ex) {
			// retry once
			try {
				queue.add(options);
			} catch (TransientFailureException reEx) {
				// failed :( what can you do
			}
		}
	}
}

@@ -1249,16 +1249,61 @@
 dexer%22;%0A
+%0A%09private static final int RETRY_COUNT = 2;%0A%0A
 %09private
@@ -1392,24 +1392,140 @@
 document) %7B%0A
+%09%09indexDocument(ALL_INDEX_NAME, document);%0A%09%7D%0A%0A%09public static void indexDocument (String name, Document document) %7B%0A
 %09%09if (docume
@@ -1547,32 +1547,38 @@
 %09%09indexDocument(
+name, 
 document, 0);%0A%09%09
@@ -1571,17 +1571,27 @@
 cument, 
-0
+RETRY_COUNT
 );%0A%09%09%7D%0A%09
@@ -1621,32 +1621,45 @@
  indexDocument (
+String name, 
 Document documen
@@ -1664,30 +1664,67 @@
 ent,
- int count) %7B%0A%09%09try %7B%0A
+%0A%09%09%09int retryCount) %7B%0A%09%09while (retryCount %3E 0) %7B%0A%09%09%09try %7B%0A%09
 %09%09%09g
@@ -1731,16 +1731,20 @@
 etIndex(
+name
 ).put(do
@@ -1752,16 +1752,37 @@
 ument);%0A
+%09%09%09%09retryCount = 0;%0A%09
 %09%09%7D catc
@@ -1798,24 +1798,25 @@
 eption e) %7B%0A
+%09
 %09%09%09if (Statu
@@ -1837,16 +1837,17 @@
 T_ERROR%0A
+%09
 %09%09%09%09%09.eq
@@ -1896,62 +1896,21 @@
 %09%09%09%09
-if (count %3C 2) %7B%0A%09%09%09%09%09indexDocument(document, count++)
+%09retryCount--
 ;%0A%09%09
@@ -2160,16 +2160,120 @@
 ntId) %7B%0A
+%09%09deleteSearch(ALL_INDEX_NAME);%0A%09%7D%0A%0A%09public static void deleteSearch (String name, String documentId) %7B%0A
 %09%09getInd
@@ -2275,16 +2275,20 @@
 etIndex(
+name
 ).delete
@@ -2336,24 +2336,109 @@
 tIndex () %7B%0A
+%09%09return getIndex(ALL_INDEX_NAME);%0A%09%7D%0A%0A%09public static Index getIndex (String name) %7B%0A
 %09%09return ens
@@ -2455,16 +2455,21 @@
 ervice()
+%0A%09%09%09%09
 .getInde
@@ -2470,21 +2470,16 @@
 etIndex(
-%0A%09%09%09%09
 IndexSpe
@@ -2501,30 +2501,20 @@
 setName(
-ALL_INDEX_NAME
+name
 ).build(

allow index name to be varied