// Path: core/src/main/java/com/sematext/solr/handler/component/SpellcheckerSuggestionProcessor.java
// public interface SpellcheckerSuggestionProcessor {
//   /**
//    * Method which will be invoked on each suggestion.
//    * 
//    * @param wordData - data about some suggestion, for instance, by using wordData.get("frequency"), frequency information
//    * @param nameValue - name of node for which data wordData is provided (for instance, when iterating over all
//    *                    incorrect words, nameValue will contain name of incorrect word)
//    * can be extracted
//    */
//   void process(NamedList<Object> wordData, String nameValue);
//   
//   /**
//    * Provides a to perform some logic after processing of all suggestions was finished.
//    */
//   void afterProcessingFinished();
// }
// 
// Path: dym/src/main/java/com/sematext/solr/handler/component/dym/ScoredSuggestion.java
// public class ScoredSuggestion implements Comparable<ScoredSuggestion> {
//   String sug;
//   double score;
//   float distance;
//   
//   public ScoredSuggestion(String sug, double score, float distance) {
//       this.sug = sug;
//       this.score = score;
//       this.distance = distance;
//   }
//   
//   public int hashCode() {
//       return sug.hashCode();
//   }
//   
//   public boolean equals(Object obj) {
//       if (obj == null) return false;
//       if (obj instanceof ScoredSuggestion == false) return false;
//       ScoredSuggestion otherSug = (ScoredSuggestion) obj;
//       return this.sug.equals(otherSug.sug);
//   }
//   
//   public int compareTo(ScoredSuggestion otherSS) {
//     double diff = this.score - otherSS.score; 
//       if (diff > 0)
//           return -1;
//       else if (diff < 0)
//           return 1;
//       else
//           return 0;
//   }
//   
//   public String toString() { return "(" + sug + "," + score + ")"; }
// }


import org.apache.lucene.search.spell.LevensteinDistance;
import org.apache.lucene.search.spell.StringDistance;
import org.apache.solr.common.util.NamedList;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.sematext.solr.handler.component.SpellcheckerSuggestionProcessor;
import com.sematext.solr.handler.component.dym.ScoredSuggestion;
/*
 *    Copyright (c) Sematext International
 *    All Rights Reserved
 *
 *    THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF Sematext International
 *    The copyright notice above does not evidence any
 *    actual or intended publication of such source code.
 */
package com.sematext.solr.handler.component.dym.processor;




public class OrderByFrequencyAndDistanceProcessor implements SpellcheckerSuggestionProcessor {
  private List<ScoredSuggestion> scoredSugs = new ArrayList<ScoredSuggestion>();
  private Iterator<String> newSuggestionsIterator;
  private boolean ignoreCollation;
  private String misspelling;
  private double topFrequency;
  
  private static final StringDistance DISTANCE = new LevensteinDistance(); // FIXME: make a solrconfig parameter
  private float distCoef = 1.0f; // FIXME: overridable via URL for experimenting?
  private float freqCoef = 0.24f; // FIXME: overridable via URL for experimenting?
  
  public OrderByFrequencyAndDistanceProcessor(Iterator<String> newSuggestionsIteratorParam, boolean ignoreCollationParam, String misspellingParam, double topFrequencyParam) {
    newSuggestionsIterator = newSuggestionsIteratorParam;
    ignoreCollation = ignoreCollationParam;
    misspelling = misspellingParam;
    topFrequency = topFrequencyParam;
  }
  
  @Override
  @SuppressWarnings("rawtypes")
  public void process(NamedList wordData, String wordName) {
    String sugString = newSuggestionsIterator.next();
    double sugFreq = ((Integer) wordData.get("freq")).doubleValue();
    
    float distance = DISTANCE.getDistance(misspelling, (String) wordData.get("word"));
    double distScore = distCoef * distance;
    double freqScore = freqCoef * (Math.sqrt(sugFreq) / topFrequency);
    double score = distScore + freqScore;
    
    // create object with sugString + score and stick it in a collection for sorting
// Path: core/src/main/java/com/sematext/solr/handler/component/SpellcheckerSuggestionProcessor.java
// public interface SpellcheckerSuggestionProcessor {
//   /**
//    * Method which will be invoked on each suggestion.
//    * 
//    * @param wordData - data about some suggestion, for instance, by using wordData.get("frequency"), frequency information
//    * @param nameValue - name of node for which data wordData is provided (for instance, when iterating over all
//    *                    incorrect words, nameValue will contain name of incorrect word)
//    * can be extracted
//    */
//   void process(NamedList<Object> wordData, String nameValue);
//   
//   /**
//    * Provides a to perform some logic after processing of all suggestions was finished.
//    */
//   void afterProcessingFinished();
// }
// 
// Path: dym/src/main/java/com/sematext/solr/handler/component/dym/ScoredSuggestion.java
// public class ScoredSuggestion implements Comparable<ScoredSuggestion> {
//   String sug;
//   double score;
//   float distance;
//   
//   public ScoredSuggestion(String sug, double score, float distance) {
//       this.sug = sug;
//       this.score = score;
//       this.distance = distance;
//   }
//   
//   public int hashCode() {
//       return sug.hashCode();
//   }
//   
//   public boolean equals(Object obj) {
//       if (obj == null) return false;
//       if (obj instanceof ScoredSuggestion == false) return false;
//       ScoredSuggestion otherSug = (ScoredSuggestion) obj;
//       return this.sug.equals(otherSug.sug);
//   }
//   
//   public int compareTo(ScoredSuggestion otherSS) {
//     double diff = this.score - otherSS.score; 
//       if (diff > 0)
//           return -1;
//       else if (diff < 0)
//           return 1;
//       else
//           return 0;
//   }
//   
//   public String toString() { return "(" + sug + "," + score + ")"; }
// }


// Path: dym/src/main/java/com/sematext/solr/handler/component/dym/processor/OrderByFrequencyAndDistanceProcessor.java
import org.apache.lucene.search.spell.LevensteinDistance;
import org.apache.lucene.search.spell.StringDistance;
import org.apache.solr.common.util.NamedList;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.sematext.solr.handler.component.SpellcheckerSuggestionProcessor;
import com.sematext.solr.handler.component.dym.ScoredSuggestion;

/*
 *    Copyright (c) Sematext International
 *    All Rights Reserved
 *
 *    THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF Sematext International
 *    The copyright notice above does not evidence any
 *    actual or intended publication of such source code.
 */
package com.sematext.solr.handler.component.dym.processor;




public class OrderByFrequencyAndDistanceProcessor implements SpellcheckerSuggestionProcessor {
  private List<ScoredSuggestion> scoredSugs = new ArrayList<ScoredSuggestion>();
  private Iterator<String> newSuggestionsIterator;
  private boolean ignoreCollation;
  private String misspelling;
  private double topFrequency;
  
  private static final StringDistance DISTANCE = new LevensteinDistance(); // FIXME: make a solrconfig parameter
  private float distCoef = 1.0f; // FIXME: overridable via URL for experimenting?
  private float freqCoef = 0.24f; // FIXME: overridable via URL for experimenting?
  
  public OrderByFrequencyAndDistanceProcessor(Iterator<String> newSuggestionsIteratorParam, boolean ignoreCollationParam, String misspellingParam, double topFrequencyParam) {
    newSuggestionsIterator = newSuggestionsIteratorParam;
    ignoreCollation = ignoreCollationParam;
    misspelling = misspellingParam;
    topFrequency = topFrequencyParam;
  }
  
  @Override
  @SuppressWarnings("rawtypes")
  public void process(NamedList wordData, String wordName) {
    String sugString = newSuggestionsIterator.next();
    double sugFreq = ((Integer) wordData.get("freq")).doubleValue();
    
    float distance = DISTANCE.getDistance(misspelling, (String) wordData.get("word"));
    double distScore = distCoef * distance;
    double freqScore = freqCoef * (Math.sqrt(sugFreq) / topFrequency);
    double score = distScore + freqScore;
    
    // create object with sugString + score and stick it in a collection for sorting
    scoredSugs.add(new ScoredSuggestion(sugString, score, distance));