package com.autonomy.abc.query;

import com.autonomy.abc.selenium.application.ApplicationType;
import com.autonomy.abc.selenium.error.Errors;
import com.autonomy.abc.selenium.query.QueryResultsPage;
import com.autonomy.abc.selenium.query.QueryService;
import com.autonomy.abc.selenium.util.Waits;
import org.hamcrest.Matcher;
import org.hamcrest.Matchers;

import java.io.Serializable;
import java.util.Arrays;
import java.util.List;

import static com.autonomy.abc.framework.ABCAssert.assertThat;
import static com.autonomy.abc.framework.ABCAssert.verifyThat;
import static com.autonomy.abc.matchers.StringMatchers.containsString;
import static com.autonomy.abc.matchers.StringMatchers.stringContainingAnyOf;
import static org.hamcrest.Matchers.allOf;
import static org.junit.Assert.fail;

public class QueryTestHelper<T extends QueryResultsPage> {
    private final static List<String> HIDDEN_BOOLEANS = Arrays.asList(
            "NOTed",
            "ANDREW",
            "ORder",
            "WHENCE",
            "SENTENCED",
            "PARAGRAPHING",
            "NEARLY",
            "SENTENCE1D",
            "PARAGRAPHING",
            "PARAGRAPH2inG",
            "SOUNDEXCLUSIVE",
            "XORING",
            "EORE",
            "DNEARLY",
            "WNEARING",
            "YNEARD",
            "AFTERWARDS",
            "BEFOREHAND",
            "NOTWHENERED"
    );

    private final QueryService<T> service;

    public QueryTestHelper(QueryService<T> queryService) {
        service = queryService;
    }

    public void hiddenQueryOperatorText(final Matcher<? super String> errorMatcher) {
        for (final String hiddenBooleansProximity : HIDDEN_BOOLEANS) {
            T page = service.search(hiddenBooleansProximity);
            Waits.loadOrFadeWait();
            assertThat("able to search for " + hiddenBooleansProximity, page.getText(), errorMatcher);
        }
    }

    public void mismatchedBracketQueryText(final Serializable invalidator) {
        List<String> queryTerms = Arrays.asList(
                "(",
                ")",
                "()",
                ") (",
                ")war"
        );

        for (String searchTerm : queryTerms) {
            String text = service.search(searchTerm).getText();
            assertThat("query term " + searchTerm + " is invalid",
                    text, containsString(invalidator));
            assertThat("query term " + searchTerm + " has sensible error message",
                    text, stringContainingAnyOf(Arrays.asList(
                            Errors.Search.INVALID,
                            Errors.Search.OPERATORS,
                            Errors.Search.STOPWORDS
                    ))
            );
        }
    }
}

@@ -30,70 +30,8 @@
 y;%0A%0A
-import com.autonomy.abc.selenium.application.ApplicationType;%0A
 impo
@@ -194,103 +194,28 @@
 ort 
-com.autonomy.abc.selenium.util.Waits;%0Aimport org.hamcrest.Matcher;%0Aimport org.hamcrest.Matchers
+org.hamcrest.Matcher
 ;%0A%0Ai
@@ -267,16 +267,43 @@
 Arrays;%0A
+import java.util.Iterator;%0A
 import j
@@ -385,71 +385,8 @@
 at;%0A
-import static com.autonomy.abc.framework.ABCAssert.verifyThat;%0A
 impo
@@ -533,88 +533,8 @@
 yOf;
-%0Aimport static org.hamcrest.Matchers.allOf;%0Aimport static org.junit.Assert.fail;
 %0A%0Apu
@@ -1377,163 +1377,54 @@
 or (
-final String hiddenBooleansProximity : HIDDEN_BOOLEANS) %7B%0A            T page = service.search(hiddenBooleansProximity);%0A            Waits.loadOrFadeWait();
+Result result : resultsFor(HIDDEN_BOOLEANS)) %7B
 %0A   
@@ -1471,37 +1471,27 @@
 %22 + 
-hiddenBooleansProximity, page
+result.term, result
 .get
@@ -1513,16 +1513,17 @@
 tcher);%0A
+%0A
         
@@ -1796,105 +1796,49 @@
 or (
-String searchTerm : queryTerms) %7B%0A            String text = service.search(searchTerm).getText();
+Result result : resultsFor(queryTerms)) %7B
 %0A   
@@ -1865,39 +1865,40 @@
 %22query term %22 + 
-searchT
+result.t
 erm + %22 is inval
@@ -1922,20 +1922,32 @@
         
-t
+result.getT
 ext
+()
 , contai
@@ -2013,15 +2013,16 @@
 %22 + 
-searchT
+result.t
 erm 
@@ -2078,12 +2078,24 @@
     
-t
+result.getT
 ext
+()
 , st
@@ -2338,11 +2338,1185 @@
  %7D%0A    %7D
+%0A%0A    private Iterable%3CResult%3E resultsFor(final Iterable%3CString%3E queries) %7B%0A        return new Iterable%3CResult%3E() %7B%0A            @Override%0A            public Iterator%3CResult%3E iterator() %7B%0A                final Iterator%3CString%3E queryIterator = queries.iterator();%0A                return new Iterator%3CResult%3E() %7B%0A                    @Override%0A                    public boolean hasNext() %7B%0A                        return queryIterator.hasNext();%0A                    %7D%0A%0A                    @Override%0A                    public Result next() %7B%0A                        final String queryTerm = queryIterator.next();%0A                        T page = service.search(queryTerm);%0A                        return new Result(queryTerm, page);%0A                    %7D%0A                %7D;%0A            %7D%0A        %7D;%0A    %7D%0A    %0A    private class Result %7B%0A        final String term;%0A        final T page;%0A        private String text;%0A%0A        Result(String term, T page) %7B%0A            this.term = term;%0A            this.page = page;%0A        %7D%0A%0A        String getText() %7B%0A            if (text == null) %7B%0A                text = page.getText();%0A            %7D%0A            return text;%0A        %7D%0A    %7D
 %0A%7D%0A

Move search result iteration logic into inner method/class