package com.kodcu.spell.dictionary;

import com.kodcu.component.EditorPane;
import com.kodcu.config.SpellcheckConfigBean;
import com.kodcu.controller.ApplicationController;
import com.kodcu.service.ThreadService;
import com.kodcu.spell.filter.SpellFilterProvider;
import morfologik.speller.Speller;
import morfologik.stemming.Dictionary;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * Created by usta on 07.12.2015.
 */
@Component
public class DictionaryService {

    private Logger logger = LoggerFactory.getLogger(DictionaryService.class);

    private final ApplicationController controller;
    private final SpellFilterProvider spellFilterProvider;
    private final ThreadService threadService;
    private final SpellcheckConfigBean spellcheckConfigBean;

    private Map<Path, LanguageSpeller> languageSpellerMap = new ConcurrentHashMap<>();
    private Map<String, List<String>> suggestionMap = new ConcurrentHashMap<>();

    @Autowired
    public DictionaryService(ApplicationController controller, SpellFilterProvider spellFilterProvider, ThreadService threadService, SpellcheckConfigBean spellcheckConfigBean) {
        this.controller = controller;
        this.spellFilterProvider = spellFilterProvider;
        this.threadService = threadService;
        this.spellcheckConfigBean = spellcheckConfigBean;
    }


    private LanguageSpeller getLanguageSpeller(Path defaultLanguage) {
        try {
            Dictionary dictionary = Dictionary.read(defaultLanguage);
            Speller speller = new Speller(dictionary);
            final LanguageSpeller languageSpeller = new LanguageSpeller();
            languageSpeller.setDictionary(dictionary);
            languageSpeller.setSpeller(speller);
            languageSpeller.setEncoding(dictionary.metadata.getEncoding());
            languageSpellerMap.putIfAbsent(defaultLanguage, languageSpeller);
            return languageSpellerMap.get(defaultLanguage);
        } catch (NullPointerException e) {
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        } finally {
            return null;
        }
    }


    public void processTokens(EditorPane editorPane, String jsonToken, String mode) {

        final Path language = Optional.ofNullable(editorPane.getSpellLanguage()).orElseGet(spellcheckConfigBean::getDefaultLanguage);

        if (Objects.isNull(language)) {
            return;
        }

        final LanguageSpeller languageSpeller = getLanguageSpeller(language);

        if (Objects.isNull(languageSpeller)) {
            return;
        }

        final List<Token> tokenList = languageSpeller.getTokenList(jsonToken);

        final List<Token> tokens = tokenList.stream()
                .flatMap(token -> token.fromLines((token.getValue())).stream())
                .filter(spellFilterProvider.filterByMode(mode))
                .filter(t -> languageSpeller.isMisspelled(t.getValue()))
                .peek(t -> {
                    final List<String> suggestions = languageSpeller.findSuggestions(t.getValue());
                    t.setEmptySuggestion(suggestions.isEmpty());
                    suggestionMap.put(t.getValue(), suggestions);
                })
                .collect(Collectors.toList());

        if (tokens.isEmpty()) {
            return;
        }

        threadService.runActionLater(() -> {
            for (Token token : tokens) {
                editorPane.addTypo(token);
            }
        });

    }

    public Map<String, List<String>> getSuggestionMap() {
        return suggestionMap;
    }
}

@@ -2398,29 +2398,18 @@
    %7D
- finally %7B%0A  
+%0A%0A
         
   re
@@ -2400,26 +2400,24 @@
  %7D%0A%0A        
-  
 return null;
@@ -2417,26 +2417,16 @@
 n null;%0A
-        %7D%0A
     %7D%0A%0A%0A

Fix return null