package com.google.sps.store;

import com.google.sps.data.Event;
import com.google.sps.data.EventResult;
import com.google.sps.data.Keyword;
import com.google.sps.utilities.KeywordHelper;
import com.google.sps.utilities.SpannerTasks;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/** Store class that uses in-memory map to hold search results. */
public class SearchStore {
  private static final float WEIGHT_IN_NAME = 0.7f;
  private static final float WEIGHT_IN_DESCRIPTION = 0.3f;
  private KeywordHelper keywordHelper;

  public SearchStore(KeywordHelper keywordHelper) {
    this.keywordHelper = keywordHelper;
  }

  /**
   * Adds keywords for name and description with mapping to eventId to index. Relevance of each
   * keyword is the weighted sum of the relevance in the name and the relevance in the description
   * where the name is weighted by value WEIGHT_IN_NAME and description is weighted by
   * WEIGHT_IN_DESCRIPTION.
   *
   * @param eventId event ID
   * @param name name of the event
   * @param description description of the event
   */
  public void addEventToIndex(String eventId, String name, String description) {
    Map<String, Float> keywordToRanking = new HashMap<String, Float>();
    addKeywordsInTextToIndex(eventId, name.toLowerCase(), WEIGHT_IN_NAME, keywordToRanking);
    addKeywordsInTextToIndex(eventId, description, WEIGHT_IN_DESCRIPTION, keywordToRanking);
    List<EventResult> entries =
        keywordToRanking.entrySet().stream()
            .map(entry -> new EventResult(eventId, entry.getKey(), entry.getValue()))
            .collect(Collectors.toList());
    SpannerTasks.addResultsToPersistentStorageIndex(entries);
  }

  /**
   * Adds result for keywords in the given text with a ranking equal to the sum of the ranking of
   * any existing event results for the eventId and the relevance of the keyword in the text
   * multiplied by the given weight.
   *
   * @param eventId event ID
   * @param text text to search keywords for
   * @param weight weight multiply relevance of keyword by which is proportional to the significance
   *     of the selected piece of text.
   * @param keywordToRanking the index to update
   */
  private void addKeywordsInTextToIndex(
      String eventId, String text, float weight, Map<String, Float> keywordToRanking) {
    keywordHelper.setContent(text);
    ArrayList<Keyword> keywords = new ArrayList<Keyword>();
    try {
      keywords = keywordHelper.getKeywords();
    } catch (IOException e) {
      System.err.println("IO Exception due to NLP library.");
    }

    for (Keyword keyword : keywords) {
      float keywordRank = 0;
      String name = keyword.getName();
      if (keywordToRanking.containsKey(name)) {
        keywordRank += keywordToRanking.get(name);
      }
      keywordRank += weight * keyword.getRelevance();
      keywordToRanking.put(keyword.getName(), keywordRank);
    }
  }

  /**
   * Gets event searchResults for the given keyword search.
   *
   * @param keyword keyword to search
   * @return list of events in descending order of ranking as search result
   */
  public static List<Event> getSearchResults(String keyword) {
    return SpannerTasks.getEventResultsByKeywordWithDescendingRanking(keyword);
  }
}

@@ -1842,187 +1842,8 @@
 text
- with a ranking equal to the sum of the ranking of%0A   * any existing event results for the eventId and the relevance of the keyword in the text%0A   * multiplied by the given weight
 .%0A  
@@ -2532,24 +2532,417 @@
 ywords) %7B%0A  
+    keywordToRanking.put(keyword.getName(), getRanking(keyword, weight, keywordToRanking));%0A    %7D%0A  %7D%0A%0A  /**%0A   * Returns ranking equal to the sum of the ranking of any existing event results for the eventId%0A   * and the relevance of the keyword in the text multiplied by the given weight.%0A   */%0A  private float getRanking(Keyword keyword, float weight, Map%3CString, Float%3E keywordToRanking) %7B%0A
     float ke
@@ -2956,18 +2956,16 @@
 nk = 0;%0A
-  
     Stri
@@ -2997,18 +2997,16 @@
 ();%0A    
-  
 if (keyw
@@ -3035,26 +3035,24 @@
 ey(name)) %7B%0A
-  
       keywor
@@ -3096,18 +3096,14 @@
     
-  
 %7D%0A    
- 
- 
 keyw
@@ -3154,49 +3154,14 @@
     
-  keywordToRanking.put(keyword.getName(),
+return
  key
@@ -3168,24 +3168,17 @@
 wordRank
-);%0A    %7D
+;
 %0A  %7D%0A%0A  

Fix from code review.