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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.StepExecutionListener;
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.BeanWrapperFieldExtractor;
import org.springframework.batch.item.file.transform.DelimitedLineAggregator;
import org.springframework.batch.item.file.transform.LineAggregator;
import org.springframework.batch.item.file.transform.PassThroughLineAggregator;
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;

import java.io.File;
import java.util.List;

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

    Logger LOGGER = LoggerFactory.getLogger(Co_occurringTermsConfiguration.class);

    public static final String COSTATS_MANUAL_COMPLETION_STEP_NAME = "costatsManualSummarizationStep";
    public static final String COSTATS_ALL_COMPLETION_STEP_NAME = "costatsAllSummarizationStep";
    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;

    @Bean
    public AnnotationCo_occurringTermsAggregator co_occurringGoTermsFromAnnotationsManual() {
        return new AnnotationCo_occurringTermsAggregator(t -> !"IEA".equals(t.evidenceCode));
    }

    @Bean
    public AnnotationCo_occurringTermsAggregator co_occurringGoTermsFromAnnotationsAll() {
        return new AnnotationCo_occurringTermsAggregator(t -> true);
    }

    @Bean
    public StepExecutionListener coTermsEndOfAggregationListener(
            AnnotationCo_occurringTermsAggregator co_occurringGoTermsFromAnnotationsManual,
            AnnotationCo_occurringTermsAggregator co_occurringGoTermsFromAnnotationsAll,
            Co_occurringTermsStatsCalculator co_occurringTermsStatsCalculatorManual,
            Co_occurringTermsStatsCalculator co_occurringTermsStatsCalculatorAll) {
        return new Co_occurringTermsStepExecutionListener(co_occurringGoTermsFromAnnotationsManual,
                co_occurringGoTermsFromAnnotationsAll, co_occurringTermsStatsCalculatorManual,
                co_occurringTermsStatsCalculatorAll);

    }

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

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

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

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

    @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());
        final File filePath = getFilePath();
        LOGGER.info("Write out co-occurring terms to {}", filePath.toString());
        Resource outputFile = new FileSystemResource(new File(filePath, 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;
    }
}

@@ -912,94 +912,18 @@
 .io.
-FileSystemResource;%0Aimport org.springframework.core.io.Resource;%0A%0Aimport java.io.File;
+Resource;%0A
 %0Aimp
@@ -1589,16 +1589,17 @@
 = %22%5Ct%22;%0A
+%0A
     @Val
@@ -1621,19 +1621,22 @@
 coterms.
-dir
+manual
 %7D%22)%0A    
@@ -1647,19 +1647,88 @@
 ate 
-String path
+Resource manual;%0A%0A    @Value(%22$%7Bindexing.coterms.all%7D%22)%0A    private Resource all
 ;%0A%0A 
@@ -3959,23 +3959,14 @@
 ter(
-%22CoStatsM
+m
 anual
-%22
 );%0A 
@@ -4091,20 +4091,11 @@
 ter(
-%22CoStatsA
+a
 ll
-%22
 );%0A 
@@ -4104,171 +4104,8 @@
  %7D%0A%0A
-    private File getFilePath() %7B%0A        File file = new File(path);%0A        if (!file.exists()) %7B%0A            file.mkdir();%0A        %7D%0A        return file;%0A    %7D%0A%0A
     
@@ -4164,38 +4164,42 @@
 tFileWriter(
-String fileNam
+Resource outputFil
 e) %7B%0A       
@@ -4281,23 +4281,25 @@
 eWriter(
-fileNam
+outputFil
 e));%0A   
@@ -4499,22 +4499,26 @@
 ter(
-String fileNam
+Resource outputFil
 e) %7B
@@ -4650,53 +4650,8 @@
 ));%0A
-        final File filePath = getFilePath();%0A
     
@@ -4708,110 +4708,28 @@
 %7D%22, 
-filePath.toString());%0A        Resource outputFile = new FileSystemResource(new File(filePath, fileName
+outputFile.toString(
 ));%0A

Remove explicit file handling for output files - keep the file name and dir as Spring Resource instances all the way.