package uk.ac.ebi.quickgo.rest.search.solr;

import uk.ac.ebi.quickgo.rest.search.AggregateFunction;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.isEmptyString;
import static org.junit.Assert.*;
import static uk.ac.ebi.quickgo.rest.search.solr.SolrAggregationHelper.*;

/**
 * Tests the behaviour of the {@link SolrAggregationHelper} class.
 */
public class SolrAggregationHelperTest {
    private static final AggregateFunction COUNT_FUNCTION = AggregateFunction.COUNT;

    private static final String GP_ID_FIELD = "geneProductId";

    @Rule
    public ExpectedException thrown = ExpectedException.none();

    @Test
    public void nullAggregateFunctionThrowsExceptionWhenCreatingAggregateFieldTitle() throws Exception {
        thrown.expect(IllegalArgumentException.class);
        thrown.expectMessage("Cannot create aggregate field title with null aggregate function");

        aggregateFieldTitle(null, GP_ID_FIELD);
    }

    @Test
    public void nullFieldThrowsExceptionWhenCreatingAggregateFieldTitle() throws Exception {
        thrown.expect(IllegalArgumentException.class);
        thrown.expectMessage("Cannot create aggregate field title with null field");

        aggregateFieldTitle(COUNT_FUNCTION, null);
    }

    @Test
    public void emptyFieldThrowsExceptionWhenCreatingAggregateFieldTitle() throws Exception {
        thrown.expect(IllegalArgumentException.class);
        thrown.expectMessage("Cannot create aggregate field title with null field");

        aggregateFieldTitle(COUNT_FUNCTION, "");
    }

    @Test
    public void validFunctionAndFieldCreateAggregateFieldTitle() throws Exception {
        String aggTitleField = aggregateFieldTitle(COUNT_FUNCTION, GP_ID_FIELD);

        assertThat(aggTitleField, is(COUNT_FUNCTION.getName() + AGG_NAME_SEPARATOR + GP_ID_FIELD));
    }

    @Test
    public void nullTypeThrowsExceptionWhenCreatingAggregateTypeTitle() throws Exception {
        thrown.expect(IllegalArgumentException.class);
        thrown.expectMessage("Cannot create aggregate type title with null or empty type");

        aggregatePrefixWithTypeTitle(null);
    }

    @Test
    public void emptyTypeThrowsExceptionWhenCreatingAggregateTypeTitle() throws Exception {
        thrown.expect(IllegalArgumentException.class);
        thrown.expectMessage("Cannot create aggregate type title with null or empty type");

        aggregatePrefixWithTypeTitle("");
    }

    @Test
    public void populatedTypeCreatesAggregateTypeTitle() throws Exception {
        String typeTitle = aggregatePrefixWithTypeTitle(GP_ID_FIELD);

        assertThat(typeTitle, is(AGG_TYPE_PREFIX + AGG_NAME_SEPARATOR + GP_ID_FIELD));
    }

    @Test
    public void nullPrefixedFieldThrowsExceptionWhenExtratingPrefix() throws Exception {
        thrown.expect(IllegalArgumentException.class);
        thrown.expectMessage("Cannot extract prefix from null input");

        fieldPrefixExtractor(null);
    }

    @Test
    public void fieldWithNoPrefixReturnsAnEmptyPrefixWhenExtratingPrefix() throws Exception {
        String prefix = fieldPrefixExtractor(GP_ID_FIELD);

        assertThat(prefix, isEmptyString());
    }

    @Test
    public void fieldWithCountPrefixReturnsAnCountPrefixWhenExtratingPrefix() throws Exception {
        String prefix = fieldPrefixExtractor(aggregateFieldTitle(COUNT_FUNCTION, GP_ID_FIELD));

        assertThat(prefix, is(COUNT_FUNCTION.getName()));
    }

    @Test
    public void nullPrefixedFieldThrowsExceptionWhenExtratingField() throws Exception {
        thrown.expect(IllegalArgumentException.class);
        thrown.expectMessage("Cannot extract field from null input");

        fieldNameExtractor(null);
    }

    @Test
    public void emptyPrefixedFieldThrowsExceptionWhenExtratingField() throws Exception {
        String fieldName = fieldNameExtractor("");

        assertThat(fieldName, isEmptyString());
    }

    @Test
    public void fieldWithCountPrefixReturnsAnTheFieldWhenExtratingField() throws Exception {
        String field = fieldNameExtractor(aggregateFieldTitle(COUNT_FUNCTION, GP_ID_FIELD));

        assertThat(field, is(GP_ID_FIELD));
    }

}
@@ -264,21 +264,29 @@
 atchers.
-e
+isE
 mpty
+String
 ;%0Aimport
@@ -301,73 +301,111 @@
 org.
-hamcrest.Matchers.isEmptyString;%0Aimport static org.junit.Assert.*
+junit.Assert.*;%0Aimport static uk.ac.ebi.quickgo.rest.search.solr.AggregateToStringConverter.NUM_BUCKETS
 ;%0Aim
@@ -2937,32 +2937,33 @@
 ceptionWhenExtra
+c
 tingPrefix() thr
@@ -2970,32 +2970,32 @@
 ows Exception %7B%0A
-
         thrown.e
@@ -3212,32 +3212,33 @@
 yPrefixWhenExtra
+c
 tingPrefix() thr
@@ -3436,24 +3436,25 @@
 fixWhenExtra
+c
 tingPrefix()
@@ -3694,32 +3694,33 @@
 ceptionWhenExtra
+c
 tingField() thro
@@ -3961,32 +3961,33 @@
 ceptionWhenExtra
+c
 tingField() thro
@@ -4180,16 +4180,17 @@
 henExtra
+c
 tingFiel
@@ -4357,9 +4357,282 @@
 %0A    %7D%0A%0A
-%7D
+    @Test%0A    public void testForNumBucketsReturnsTrue()%7B%0A        assertThat(distinctValueCountTester(NUM_BUCKETS), is(true)) ;%0A    %7D%0A%0A    @Test%0A    public void testForNumBucketsReturnsFalse()%7B%0A        assertThat(distinctValueCountTester(%22bucketHead%22), is(false)) ;%0A    %7D%0A%7D%0A

Add tests for number of buckets field assessor.