//
//  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 final int RETRY_COUNT = 2;

	private static SearchService searchService;

	public static void indexDocument (Document document) {
		indexDocument(ALL_INDEX_NAME, document);
	}

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

	private static void indexDocument (String name, Document document,
			int retryCount) {
		while (retryCount > 0) {
			try {
				getIndex(name).put(document);
				retryCount = 0;
			} catch (PutException e) {
				if (StatusCode.TRANSIENT_ERROR
						.equals(e.getOperationResult().getCode())) {
					retryCount--;
				}
			}
		}
	}

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

		return searchService;
	}

	public static void deleteSearch (String documentId) {
		deleteSearch(ALL_INDEX_NAME);
	}

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

	public static Index getIndex () {
		return getIndex(ALL_INDEX_NAME);
	}

	public static Index getIndex (String name) {
		return ensureSearchService()
				.getIndex(IndexSpec.newBuilder().setName(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
			}
		}
	}
}

@@ -1290,17 +1290,17 @@
 COUNT = 
-2
+3
 ;%0A%0A%09priv
@@ -1677,41 +1677,16 @@
 etry
-Count
 ) %7B%0A%09%09
-while (retryCount %3E 0)
+do
  %7B%0A%09
@@ -1736,21 +1736,16 @@
 %09%09%09retry
-Count
  = 0;%0A%09%09
@@ -1872,31 +1872,126 @@
 etry
-Count--;%0A%09%09%09%09%7D%0A%09%09%09%7D%0A%09%09%7D
+--;%0A%09%09%09%09%7D else %7B%0A%09%09%09%09%09// if it is not a transient error we just stop%0A%09%09%09%09%09retry = 0;%0A%09%09%09%09%7D%0A%09%09%09%7D%0A%09%09%7D while (retry %3E 0);
 %0A%09%7D%0A
@@ -3083,22 +3083,58 @@
 ());%0A%0A%09%09
-try %7B%0A
+int retry = RETRY_COUNT;%0A%09%09do %7B%0A%09%09%09try %7B%0A%09
 %09%09%09queue
@@ -3152,99 +3152,54 @@
 s);%0A
+%0A
 %09%09
-%7D catch (TransientFailureException ex) %7B%0A%09%09%09// retry once%0A
+%09%09// success no need to retry%0A%09
 %09%09%09
+re
 try 
-%7B%0A%09%09%09%09queue.add(options)
+= 0
 ;%0A%09%09
@@ -3234,19 +3234,17 @@
 ception 
-reE
+e
 x) %7B%0A%09%09%09
@@ -3248,45 +3248,44 @@
 %09%09%09%09
-// failed :( what can you do%0A%09%09%09%7D%0A%09%09%7D
+retry--;%0A%09%09%09%7D%0A%09%09%7D while (retry %3E 0);
 %0A%09%7D%0A

use same structure for retry in search