package uk.ac.ebi.quickgo.annotation.service.comm.rest.ontology.slim;

import uk.ac.ebi.quickgo.annotation.model.Annotation;
import uk.ac.ebi.quickgo.annotation.service.comm.rest.ontology.converter.SlimmingConversionInfo;
import uk.ac.ebi.quickgo.annotation.service.comm.rest.ontology.transformer.SlimResultsTransformer;
import uk.ac.ebi.quickgo.rest.comm.FilterContext;
import uk.ac.ebi.quickgo.rest.search.results.QueryResult;

import java.util.ArrayList;
import org.junit.Before;
import org.junit.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.core.Is.is;

/**
 * Created 11/08/16
 * @author Edd
 */
public class SlimResultsTransformerTest {

    private SlimResultsTransformer transformer;
    private FilterContext context;
    private ArrayList<Annotation> results;
    private SlimmingConversionInfo conversionInfo;

    @Before
    public void setUp() {
        conversionInfo = new SlimmingConversionInfo();
        transformer = new SlimResultsTransformer();
        context = new FilterContext();
        context.save(SlimmingConversionInfo.class, conversionInfo);
        results = new ArrayList<>();
    }

    @Test
    public void emptyContextOnEmptyResultsCausesNoTransformation() {
        QueryResult<Annotation> emptyQueryResult = createQueryResult();
        QueryResult<Annotation> transformedResults = transformer.transform(emptyQueryResult, context);

        assertThat(transformedResults, is(emptyQueryResult));
    }

    @Test
    public void emptyContextOnExistingResultsCausesNoTransformation() {
        addAnnotationToResults("goId1");

        QueryResult<Annotation> queryResult = createQueryResult();
        QueryResult<Annotation> transformedResults = transformer.transform(queryResult, context);

        assertThat(transformedResults.getResults(), hasSize(1));
        assertThat(transformedResults, is(queryResult));
    }

    @Test
    public void resultThatMatchesSlimTermInContextIsTransformed() {
        String goId1 = "goId1";
        String slimmedId1 = "slimmedId1";

        addAnnotationToResults(goId1);
        addKnownMapping(goId1, slimmedId1);

        QueryResult<Annotation> queryResult = createQueryResult();
        QueryResult<Annotation> transformedResults = transformer.transform(queryResult, context);

        assertThat(transformedResults.getResults(), hasSize(1));
        Annotation transformedAnnotation = transformedResults.getResults().get(0);
        assertThat(transformedAnnotation.goId, is(goId1));
        assertThat(transformedAnnotation.slimmedIds, contains(slimmedId1));
    }

    @Test
    public void resultThatDoesNotMatchSlimTermInContextIsNotTransformed() {
        String goId1 = "goId1";
        addAnnotationToResults(goId1);

        String goId2 = "goId2";
        String slimmedId1 = "slimmedId1";
        addKnownMapping(goId2, slimmedId1);

        QueryResult<Annotation> queryResult = createQueryResult();
        QueryResult<Annotation> transformedResults = transformer.transform(queryResult, context);

        assertThat(transformedResults.getResults(), hasSize(1));

        Annotation nonTransformedAnnotation1 = transformedResults.getResults().get(0);
        assertThat(nonTransformedAnnotation1.goId, is(goId1));
        assertThat(nonTransformedAnnotation1.slimmedIds, is(nullValue()));
    }

    private void addAnnotationToResults(String goId) {
        Annotation annotation = new Annotation();
        annotation.goId = goId;
        results.add(annotation);
    }

    private void addKnownMapping(String originalGOId, String... slimmedGOIds) {
        for (String slimmedGOId : slimmedGOIds) {
            conversionInfo.addOriginal2SlimmedGOIdMapping(originalGOId, slimmedGOId);
        }
    }

    private QueryResult<Annotation> createQueryResult() {
        return new QueryResult.Builder<>(results.size(), results).build();
    }
}
@@ -2052,33 +2052,735 @@
     public void 
-r
+oneResultThatMatchesOneSlimTermInContextIsTransformed() %7B%0A        String goId1 = %22goId1%22;%0A        String slimmedId1 = %22slimmedId1%22;%0A%0A        addAnnotationToResults(goId1);%0A        addKnownMapping(goId1, slimmedId1);%0A%0A        QueryResult%3CAnnotation%3E queryResult = createQueryResult();%0A        QueryResult%3CAnnotation%3E transformedResults = transformer.transform(queryResult, context);%0A%0A        assertThat(transformedResults.getResults(), hasSize(1));%0A        Annotation transformedAnnotation = transformedResults.getResults().get(0);%0A        assertThat(transformedAnnotation.goId, is(goId1));%0A        assertThat(transformedAnnotation.slimmedIds, contains(slimmedId1));%0A    %7D%0A%0A    @Test%0A    public void oneR
 esultThatMatches
@@ -2779,24 +2779,27 @@
 tMatches
+Two
 SlimTerm
 InContex
@@ -2782,32 +2782,33 @@
 tchesTwoSlimTerm
+s
 InContextIsTrans
@@ -2883,32 +2883,74 @@
  = %22slimmedId1%22;
+%0A        String slimmedId2 = %22slimmedId2%22;
 %0A%0A        addAnn
@@ -3009,32 +3009,76 @@
 d1, slimmedId1);
+%0A        addKnownMapping(goId1, slimmedId2);
 %0A%0A        QueryR
@@ -3428,32 +3428,32 @@
 Id, is(goId1));%0A
-
         assertTh
@@ -3500,32 +3500,44 @@
 tains(slimmedId1
+, slimmedId2
 ));%0A    %7D%0A%0A    @

test to check slimming result transformation when goId maps to >1 slimmedId