package uk.ac.ebi.quickgo.annotation.controller;

import uk.ac.ebi.quickgo.annotation.AnnotationREST;
import uk.ac.ebi.quickgo.annotation.common.AnnotationDocument;
import uk.ac.ebi.quickgo.annotation.common.AnnotationRepository;
import uk.ac.ebi.quickgo.common.store.TemporarySolrDataStore;

import java.util.List;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.is;
import static org.springframework.http.HttpHeaders.ACCEPT;
import static org.springframework.http.HttpHeaders.CONTENT_DISPOSITION;
import static org.springframework.http.HttpHeaders.VARY;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request;
import static uk.ac.ebi.quickgo.annotation.common.document.AnnotationDocMocker.createGenericDocsChangingGoId;
import static uk.ac.ebi.quickgo.annotation.controller.ResponseVerifier.numOfResults;
import static uk.ac.ebi.quickgo.annotation.download.http.MediaTypeFactory.EXCEL_MEDIA_TYPE;
import static uk.ac.ebi.quickgo.annotation.download.http.MediaTypeFactory.JSON_MEDIA_TYPE;
import static uk.ac.ebi.quickgo.annotation.download.http.MediaTypeFactory.fileExtension;
/**
 * @author Tony Wardell
 * Date: 10/10/2017
 * Time: 13:41
 * Created with IntelliJ IDEA.
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {AnnotationREST.class})
@WebAppConfiguration
public class AnnotationControllerStatisticsDownloadIT {
    // temporary data store for solr's data, which is automatically cleaned on exit
    @ClassRule
    public static final TemporarySolrDataStore solrDataStore = new TemporarySolrDataStore();
    private static final int NUMBER_OF_GENERIC_DOCS = 50;
    private static final String DOWNLOAD_STATISTICS_SEARCH_URL = "/annotation/downloadStats";
    private static final String NUMBER_OF_GO_ID_RESULTS_FOR_ANNOTATIONS =
            "$.results[0].types.[?(@.type == 'goId')].values.length()";

    private MockMvc mockMvc;

    @Autowired
    private WebApplicationContext webApplicationContext;

    @Autowired
    private AnnotationRepository repository;

    @Before
    public void setup() {
        repository.deleteAll();

        mockMvc = MockMvcBuilders.
                                         webAppContextSetup(webApplicationContext)
                                 .build();

        List<AnnotationDocument> genericDocs = createDocs(NUMBER_OF_GENERIC_DOCS);
        saveToRepo(genericDocs);
    }

    @Test
    public void canDownloadInExcelFormatAfterFailedToLoadGONamesAndTaxonNames() throws Exception {
        canDownload(EXCEL_MEDIA_TYPE);
    }

    @Test
    public void canDownloadWithInJsonFormatAfterFailedToLoadGONamesAndTaxonNames() throws Exception {
        canDownload(JSON_MEDIA_TYPE,6);
    }

    private List<AnnotationDocument> createDocs(int number) {
        return createGenericDocsChangingGoId(number);
    }

    private void saveToRepo(List<AnnotationDocument> docsToSave) {
        repository.save(docsToSave);
    }

    private void canDownload(MediaType mediaType) throws Exception {
        ResultActions response = mockMvc.perform(
                get(DOWNLOAD_STATISTICS_SEARCH_URL)
                        .header(ACCEPT, mediaType));
        checkResponse(mediaType, response);
    }

    private void canDownload(MediaType mediaType, int expectedSize) throws Exception {
        ResultActions response = mockMvc.perform(
                get(DOWNLOAD_STATISTICS_SEARCH_URL)
                        .header(ACCEPT, mediaType));
        checkResponse(mediaType, response, expectedSize);
    }

    private void checkResponse(MediaType mediaType, ResultActions response) throws Exception {
        response.andExpect(request().asyncStarted())
                .andDo(MvcResult::getAsyncResult)
                .andDo(print())
                .andExpect(header().string(VARY, is(ACCEPT)))
                .andExpect(header().string(CONTENT_DISPOSITION, endsWith("." + fileExtension(mediaType) + "\"")))
                .andExpect(content().contentType(mediaType));
    }

    private void checkResponse(MediaType mediaType, ResultActions response, int expectedSize) throws Exception {
        checkResponse(mediaType, response);
        response.andExpect(numOfResults(NUMBER_OF_GO_ID_RESULTS_FOR_ANNOTATIONS, expectedSize));
    }

}

@@ -2208,16 +2208,17 @@
 ension;%0A
+%0A
 /**%0A * @
@@ -3255,33 +3255,8 @@
 rs.%0A
-                         
     
@@ -3309,33 +3309,16 @@
 ontext)%0A
-                 
         
@@ -3463,322 +3463,8 @@
  %7D%0A%0A
-    @Test%0A    public void canDownloadInExcelFormatAfterFailedToLoadGONamesAndTaxonNames() throws Exception %7B%0A        canDownload(EXCEL_MEDIA_TYPE);%0A    %7D%0A%0A    @Test%0A    public void canDownloadWithInJsonFormatAfterFailedToLoadGONamesAndTaxonNames() throws Exception %7B%0A        canDownload(JSON_MEDIA_TYPE,6);%0A    %7D%0A%0A
     
@@ -3685,32 +3685,187 @@
 ToSave);%0A    %7D%0A%0A
+    @Test%0A    public void canDownloadInExcelFormatAfterFailedToLoadGONamesAndTaxonNames() throws Exception %7B%0A        canDownload(EXCEL_MEDIA_TYPE);%0A    %7D%0A%0A
     private void
@@ -4127,315 +4127,8 @@
  %7D%0A%0A
-    private void canDownload(MediaType mediaType, int expectedSize) throws Exception %7B%0A        ResultActions response = mockMvc.perform(%0A                get(DOWNLOAD_STATISTICS_SEARCH_URL)%0A                        .header(ACCEPT, mediaType));%0A        checkResponse(mediaType, response, expectedSize);%0A    %7D%0A%0A
     
@@ -4590,32 +4590,499 @@
 aType));%0A    %7D%0A%0A
+    @Test%0A    public void canDownloadWithInJsonFormatAfterFailedToLoadGONamesAndTaxonNames() throws Exception %7B%0A        canDownload(JSON_MEDIA_TYPE, 6);%0A    %7D%0A%0A    private void canDownload(MediaType mediaType, int expectedSize) throws Exception %7B%0A        ResultActions response = mockMvc.perform(%0A                get(DOWNLOAD_STATISTICS_SEARCH_URL)%0A                        .header(ACCEPT, mediaType));%0A        checkResponse(mediaType, response, expectedSize);%0A    %7D%0A%0A
     private void

Reformat code.