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

import uk.ac.ebi.quickgo.index.annotation.Annotation;

import java.io.File;
import java.util.List;
import java.util.function.Predicate;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.file.FlatFileHeaderCallback;
import org.springframework.batch.item.file.FlatFileItemWriter;
import org.springframework.batch.item.file.transform.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;

/**
 * @author Tony Wardell
 * Date: 08/09/2016
 * Time: 11:07
 * Created with IntelliJ IDEA.
 */
@Configuration
public class Co_occurringTermsConfiguration {

    private static final String[] FF_COL_NAMES = {"target", "comparedTerm", "probabilityRatio", "similarityRatio",
            "together", "compared"};
    private static final String DELIMITER = "\t";

    @Value("${indexing.coterms.dir}")
    private String path;

    public static final String COSTATS_MANUAL_COMPLETION_STEP_NAME = "costatsManualSummarizationStep";
    public static final String COSTATS_ALL_COMPLETION_STEP_NAME = "costatsAllSummarizationStep";

    @Bean
    AnnotationCo_occurringTermsAggregator annotationCo_occurringTermsAggregatorMan() {
        return new AnnotationCo_occurringTermsAggregator();
    }

    @Bean
    AnnotationCo_occurringTermsAggregator annotationCo_occurringTermsAggregatorAll() {
        return new AnnotationCo_occurringTermsAggregator();
    }

    @Bean
    public ItemProcessor<Annotation, Annotation> co_occurringGoTermsFromAnnotationsManual(
            AnnotationCo_occurringTermsAggregator annotationCo_occurringTermsAggregatorMan) {
        Predicate<Annotation> toBeProcessed = t -> !"IEA".equals(t.evidenceCode);
        return new Co_occurringGoTermsFromAnnotations(annotationCo_occurringTermsAggregatorMan, toBeProcessed);
    }

    @Bean
    public ItemProcessor<Annotation, Annotation> co_occurringGoTermsFromAnnotationsAll(
            AnnotationCo_occurringTermsAggregator annotationCo_occurringTermsAggregatorAll) {
        Predicate<Annotation> toBeProcessed = t -> true;
        return new Co_occurringGoTermsFromAnnotations(annotationCo_occurringTermsAggregatorAll, toBeProcessed);
    }

    @Bean
    public Co_occurringTermsStepExecutionListener coTermsEndOfAggregationListener(
            AnnotationCo_occurringTermsAggregator annotationCo_occurringTermsAggregatorAll,
            AnnotationCo_occurringTermsAggregator annotationCo_occurringTermsAggregatorMan,
            Co_occurringTermsStatsCalculator co_occurringTermsStatsCalculatorManual,
            Co_occurringTermsStatsCalculator co_occurringTermsStatsCalculatorAll) {
        return new Co_occurringTermsStepExecutionListener(annotationCo_occurringTermsAggregatorAll,
                annotationCo_occurringTermsAggregatorMan, co_occurringTermsStatsCalculatorManual,
                co_occurringTermsStatsCalculatorAll);

    }

    @Bean
    public Co_occurringTermsStatsCalculator co_occurringTermsStatsCalculatorManual(
            AnnotationCo_occurringTermsAggregator annotationCo_occurringTermsAggregatorMan) {
        return new Co_occurringTermsStatsCalculator(annotationCo_occurringTermsAggregatorMan);
    }

    @Bean
    public Co_occurringTermsStatsCalculator co_occurringTermsStatsCalculatorAll(
            AnnotationCo_occurringTermsAggregator annotationCo_occurringTermsAggregatorAll) {
        return new Co_occurringTermsStatsCalculator(annotationCo_occurringTermsAggregatorAll);
    }

    @Bean
    public ItemReader<String> coStatsManualItemReader(AnnotationCo_occurringTermsAggregator annotationCo_occurringTermsAggregatorMan) {
        return new Co_occurringTermItemReader(annotationCo_occurringTermsAggregatorMan);
    }

    @Bean
    public ItemReader<String> coStatsAllItemReader(AnnotationCo_occurringTermsAggregator annotationCo_occurringTermsAggregatorAll) {
        return new Co_occurringTermItemReader(annotationCo_occurringTermsAggregatorAll);
    }

    @Bean
    ItemWriter<List<Co_occurringTerm>> coStatManualFlatFileWriter() {
        return listItemFlatFileWriter("CoStatsManual");
    }

    @Bean
    ItemWriter<List<Co_occurringTerm>> coStatsAllFlatFileWriter() {
        return listItemFlatFileWriter("CoStatsAll");
    }

    private File getFilePath() {
        File file = new File(path);
        if (!file.exists()) {
            file.mkdir();
        }
        return file;
    }

    private ListItemWriter<Co_occurringTerm> listItemFlatFileWriter(String fileName) {
        ListItemWriter<Co_occurringTerm> listWriter = new ListItemWriter<>(flatFileWriter(fileName));
        listWriter.setLineAggregator(new PassThroughLineAggregator<>()); //this shouldn't do anything
        return listWriter;
    }

    private FlatFileItemWriter<Co_occurringTerm> flatFileWriter(String fileName) {
        FlatFileItemWriter<Co_occurringTerm> ffw = new FlatFileItemWriter<>();
        ffw.setLineAggregator(lineAggregator());
        Resource outputFile = new FileSystemResource(new File(getFilePath(), fileName));
        ffw.setResource(outputFile);
        FlatFileHeaderCallback headerCallBack = new Co_occurringTermsFlatFileHeaderCallBack();
        ffw.setHeaderCallback(headerCallBack);
        return ffw;
    }

    private LineAggregator<Co_occurringTerm> lineAggregator() {
        DelimitedLineAggregator<Co_occurringTerm> delimitedLineAggregator = new DelimitedLineAggregator<>();
        delimitedLineAggregator.setDelimiter(DELIMITER);
        delimitedLineAggregator.setFieldExtractor(beanWrapperFieldExtractor());
        return delimitedLineAggregator;
    }

    private BeanWrapperFieldExtractor<Co_occurringTerm> beanWrapperFieldExtractor() {
        BeanWrapperFieldExtractor<Co_occurringTerm> beanWrapperFieldExtractor = new BeanWrapperFieldExtractor<>();
        beanWrapperFieldExtractor.setNames(FF_COL_NAMES);
        return beanWrapperFieldExtractor;
    }
}

@@ -1949,90 +1949,8 @@
 ) %7B%0A
-        Predicate%3CAnnotation%3E toBeProcessed = t -%3E !%22IEA%22.equals(t.evidenceCode);%0A
     
@@ -2040,30 +2040,67 @@
 atorMan,
- toBeProcessed
+%0A                t -%3E !%22IEA%22.equals(t.evidenceCode)
 );%0A    %7D
@@ -2297,65 +2297,8 @@
 ) %7B%0A
-        Predicate%3CAnnotation%3E toBeProcessed = t -%3E true;%0A
     
@@ -2394,20 +2394,16 @@
 l, t
-oBeProcessed
+ -%3E true
 );%0A 

Remove un-necessary instance variables.