package org.jabref.logic.importer.fetcher;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import org.jabref.logic.importer.ImportFormatPreferences;
import org.jabref.logic.importer.ParseException;
import org.jabref.logic.importer.SearchBasedFetcher;
import org.jabref.logic.importer.fileformat.BibtexParser;
import org.jabref.logic.importer.util.GrobidService;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.util.DummyFileUpdateMonitor;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class GrobidCitationFetcher implements SearchBasedFetcher {

    private static final Logger LOGGER = LoggerFactory.getLogger(GrobidCitationFetcher.class);
    private static final String GROBID_URL = "http://grobid.jabref.org:8070";
    private ImportFormatPreferences importFormatPreferences;
    private GrobidService grobidService;

    public GrobidCitationFetcher(ImportFormatPreferences importFormatPreferences) {
        this.importFormatPreferences = importFormatPreferences;
        this.grobidService = new GrobidService(GROBID_URL);
    }

    /**
     * Passes request to grobid server, using consolidateCitations option to improve result. Takes a while, since the
     * server has to look up the entry.
     *
     * @return A BibTeX string if extraction is successful
     */
    private Optional<String> parseUsingGrobid(String plainText) {
        try {
            return Optional.of(grobidService.processCitation(plainText, GrobidService.ConsolidateCitations.WITH_METADATA));
        } catch (IOException e) {
            LOGGER.debug("Could not process citation", e);
            return Optional.empty();
        }
    }

    private Optional<BibEntry> parseBibToBibEntry(String bibtexString) {
        try {
            return BibtexParser.singleFromString(bibtexString,
                    importFormatPreferences, new DummyFileUpdateMonitor());
        } catch (ParseException e) {
            return Optional.empty();
        }
    }

    @Override
    public List<BibEntry> performSearch(String query) {
        List<String> plainReferences = Arrays
                .stream(query.split("\\r\\r+|\\n\\n+|\\r\\n(\\r\\n)+"))
                .map(String::trim)
                .filter(str -> !str.isBlank())
                .collect(Collectors.toCollection(ArrayList::new));
        if (plainReferences.isEmpty()) {
            return Collections.emptyList();
        } else {
            return plainReferences
                    .stream()
                    .map(reference -> parseUsingGrobid(reference))
                    .flatMap(Optional::stream)
                    .map(reference -> parseBibToBibEntry(reference))
                    .flatMap(Optional::stream)
                    .collect(Collectors.toList());
        }
    }

    @Override
    public String getName() {
        return "GROBID";
    }
}

@@ -2207,38 +2207,14 @@
     
-List%3CString%3E plainReferences =
+return
  Arr
@@ -2375,246 +2375,8 @@
 ())%0A
-                .collect(Collectors.toCollection(ArrayList::new));%0A        if (plainReferences.isEmpty()) %7B%0A            return Collections.emptyList();%0A        %7D else %7B%0A            return plainReferences%0A                    .stream()%0A    
     
@@ -2442,36 +2442,32 @@
                 
-  
-  
 .flatMap(Optiona
@@ -2469,36 +2469,32 @@
 tional::stream)%0A
-    
                 
@@ -2550,36 +2550,32 @@
                 
-  
-  
 .flatMap(Optiona
@@ -2577,36 +2577,32 @@
 tional::stream)%0A
-    
                 
@@ -2632,26 +2632,16 @@
 ist());%0A
-        %7D%0A
     %7D%0A%0A 

Optimize stream() code