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

import uk.ac.ebi.quickgo.annotation.common.AnnotationRepository;
import uk.ac.ebi.quickgo.annotation.common.document.AnnotationDocument;
import uk.ac.ebi.quickgo.common.solr.TemporarySolrDataStore;
import uk.ac.ebi.quickgo.index.annotation.coterms.CoTermTemporaryDataStore;
import uk.ac.ebi.quickgo.index.common.JobTestRunnerConfig;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.test.JobLauncherTestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.SpringApplicationContextLoader;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.hasSize;
import static org.springframework.test.util.MatcherAssertionErrors.assertThat;
import static uk.ac.ebi.quickgo.index.annotation.AnnotationConfig.ANNOTATION_INDEXING_JOB_NAME;
import static uk.ac.ebi.quickgo.index.annotation.AnnotationConfig.ANNOTATION_INDEXING_STEP_NAME;
import static uk.ac.ebi.quickgo.index.annotation.coterms.CoTermsConfig.COTERM_ALL_COMPLETION_STEP_NAME;
import static uk.ac.ebi.quickgo.index.annotation.coterms.CoTermsConfig.COTERM_MANUAL_COMPLETION_STEP_NAME;

/**
 * Tests whether Spring Batch is correctly wired up to run the annotation indexing.
 *
 * Created 22/04/16
 * @author Edd
 */
@ActiveProfiles(profiles = {"embeddedServer"})
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(
        classes = {AnnotationConfig.class, JobTestRunnerConfig.class, CoTermTemporaryDataStore.Config.class},
        loader = SpringApplicationContextLoader.class)
public class AnnotationIndexingBatchIT {

    @ClassRule
    public static final CoTermTemporaryDataStore coTermsDataStore = new CoTermTemporaryDataStore();

    @ClassRule
    public static final TemporarySolrDataStore solrDataStore = new TemporarySolrDataStore();

    @Autowired
    private JobLauncherTestUtils jobLauncherTestUtils;

    @Autowired
    private AnnotationRepository annotationRepository;

    @Test
    public void successfulIndexingJob() throws Exception {
        JobExecution jobExecution = jobLauncherTestUtils.launchJob();
        assertThat(jobExecution.getJobInstance().getJobName(), is(ANNOTATION_INDEXING_JOB_NAME));

        List<StepExecution> jobsSingleStepAsList = jobExecution.getStepExecutions()
                .stream()
                .filter(step -> step.getStepName().equals (ANNOTATION_INDEXING_STEP_NAME))
                .collect(Collectors.toList());
        assertThat(jobsSingleStepAsList, hasSize(1));

        StepExecution indexingStep = jobsSingleStepAsList.get(0);

        assertThat(indexingStep.getReadCount(), is(7));
        assertThat(indexingStep.getReadSkipCount(), is(0));
        assertThat(indexingStep.getProcessSkipCount(), is(2));
        assertThat(indexingStep.getWriteCount(), is(5));

        List<String> writtenAnnotationDocGeneProductIds =
                getGeneProductIdsFromAnnotationDocuments(annotationRepository.findAll());

        assertThat(writtenAnnotationDocGeneProductIds, containsInAnyOrder(
                "IntAct:EBI-10043081",
                "IntAct:EBI-10043081",
                "IntAct:EBI-10205244",
                "IntAct:EBI-8801830",
                "IntAct:EBI-10043089"
        ));

        //Manual
        List<StepExecution> jobsSingleStepCoTermManual = jobExecution.getStepExecutions()
                .stream()
                .filter(step -> step.getStepName().equals (COTERM_MANUAL_COMPLETION_STEP_NAME))
                .collect(Collectors.toList());
        assertThat(jobsSingleStepCoTermManual, hasSize(1));
        StepExecution coTermsManualStep = jobsSingleStepCoTermManual.get(0);
        assertThat(coTermsManualStep.getReadCount(), is(4));
        assertThat(coTermsManualStep.getReadSkipCount(), is(0));
        assertThat(coTermsManualStep.getProcessSkipCount(), is(0));
        assertThat(coTermsManualStep.getWriteCount(), is(4));

        List<StepExecution> jobsSingleStepCoTermAll = jobExecution.getStepExecutions()
                .stream()
                .filter(step -> step.getStepName().equals (COTERM_ALL_COMPLETION_STEP_NAME))
                .collect(Collectors.toList());
        assertThat(jobsSingleStepCoTermAll, hasSize(1));
        StepExecution coTermsAllStep = jobsSingleStepCoTermAll.get(0);
        assertThat(coTermsAllStep.getReadCount(), is(5));
        assertThat(coTermsAllStep.getReadSkipCount(), is(0));
        assertThat(coTermsAllStep.getProcessSkipCount(), is(0));
        assertThat(coTermsAllStep.getWriteCount(), is(5));

        //Has finished
        BatchStatus status = jobExecution.getStatus();
        assertThat(status, is(BatchStatus.COMPLETED));

    }

    private List<String> getGeneProductIdsFromAnnotationDocuments(Iterable<AnnotationDocument> repoDocsWritten) {
        return StreamSupport.stream(repoDocsWritten.spliterator(), false).map(i -> i.geneProductId).collect(Collectors
                .toList());
    }
}

@@ -519,75 +519,12 @@
 nit.
-Rule;%0Aimport org.junit.Test;%0Aimport org.junit.rules.TemporaryFolder
+Test
 ;%0Aim
@@ -837,67 +837,8 @@
 ed;%0A
-import org.springframework.beans.factory.annotation.Value;%0A
 impo
@@ -1579,24 +1579,25 @@
 rmsConfig.CO
+_
 TERM_ALL_COM
@@ -1585,38 +1585,41 @@
 fig.CO_TERM_ALL_
-COMPLE
+SUMMARIZA
 TION_STEP_NAME;%0A
@@ -1607,29 +1607,24 @@
 IZATION_STEP
-_NAME
 ;%0Aimport sta
@@ -1686,16 +1686,17 @@
 onfig.CO
+_
 TERM_MAN
@@ -1691,38 +1691,41 @@
 .CO_TERM_MANUAL_
-COMPLE
+SUMMARIZA
 TION_STEP_NAME;%0A
@@ -1717,21 +1717,16 @@
 ION_STEP
-_NAME
 ;%0A%0A/**%0A 
@@ -3999,24 +3999,25 @@
 ).equals (CO
+_
 TERM_MANUAL_
@@ -4016,22 +4016,25 @@
 _MANUAL_
-COMPLE
+SUMMARIZA
 TION_STE
@@ -4026,37 +4026,32 @@
 MMARIZATION_STEP
-_NAME
 ))%0A             
@@ -4652,16 +4652,17 @@
 uals (CO
+_
 TERM_ALL
@@ -4662,22 +4662,25 @@
 ERM_ALL_
-COMPLE
+SUMMARIZA
 TION_STE
@@ -4676,29 +4676,24 @@
 IZATION_STEP
-_NAME
 ))%0A         

Rename coterm steps.