package com.google.sps.data;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.sps.data.Book;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class GenreRecommender {
  private List<Book> books;
  private Map<Book, Set<String>> bookToGenres;
  private Map<String, Set<Book>> genreToBooks;

  public GenreRecommender(List<Book> books) {
    this.books = books;
    bookToGenres = new HashMap<Book, Set<String>>();
    genreToBooks = new HashMap<String, Set<Book>>();
    for (Book book : books) {
      Set<String> genres = getGenreSet(book.genre());
      bookToGenres.put(book, genres);
      for (String genre : genres) {
        if (genreToBooks.containsKey(genre)) {
          genreToBooks.get(genre).add(book);
        } else {
          genreToBooks.put(genre, Sets.newHashSet(book));
        }
      }
    }
  }

  private Set<String> getGenreSet(String genreString) {
    Set<String> genres = new HashSet<String>();
    for (String genre : genreString.toLowerCase().split(";")) {
      genres.add(genre);
    }
    return genres;
  }

  public ImmutableSet<String> getGenres(Book book) {
    Set<String> genres = bookToGenres.get(book);
    if (genres == null) {
      return ImmutableSet.of();
    }
    return ImmutableSet.copyOf(genres);
  }

  public ImmutableSet<Book> getBooksWithExactGenres(Set<String> genres) {
    Set<Book> matchingBooks = new HashSet<Book>();
    for (Book book : bookToGenres.keySet()) {
      if (bookToGenres.get(book).equals(genres)) {
        matchingBooks.add(book);
      }
    }
    if (matchingBooks.isEmpty()) {
      return ImmutableSet.of();
    }
    return ImmutableSet.copyOf(matchingBooks);
  }
}
@@ -518,16 +518,206 @@
 Books;%0A%0A
+  /** %0A   * Constructor that takes in a list of books %0A   * and populates class variables appropriately.%0A   *%0A   * @param books: List of Book objects for the recommendation algorithm%0A   */ %0A
   public
@@ -1233,24 +1233,241 @@
 %7D%0A    %7D%0A  %7D%0A
+ %0A  /**%0A  * Helper method that takes in the list of genres as a %22;%22-separated string%0A  * and returns a set of genres %0A  * %0A  * @param genreString: %22;%22-separated string of genres%0A  * @return ImmutableSet of genres%0A  */
 %0A  private S
@@ -1465,16 +1465,25 @@
 private 
+Immutable
 Set%3CStri
@@ -1678,21 +1678,208 @@
 urn 
+ImmutableSet.copyOf(
 genres
+)
 ;%0A  %7D%0A%0A
+  /**%0A  * Takes in a Book object and returns a set of genres %0A  * of that book%0A  * %0A  * @param book: Book object%0A  * @return ImmutableSet of genres of that book%0A  */%0A
   pu
@@ -2085,16 +2085,254 @@
 );%0A  %7D%0A%0A
+  /**%0A  * Takes in a set of genres and returns a set of Book objects%0A  * that have exactly the genres from the set. %0A  * %0A  * @param genres: Set of genres (as Strings)%0A  * @return ImmutableSet of books that have exactly these genres%0A  */%0A
   public

add javadoc