package com.allendowney.thinkdast;

import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import redis.clients.jedis.Jedis;


/**
 * Reprezentuje wyniki zapytania.
 *
 */
public class WikiSearch {

   // mapa odwzorowująca ciągi URL wskazujące strony, które zawierają słowo (lub słowa), na oceny trafności
   private Map<String, Integer> map;

   /**
    * Konstruktor.
    *
    * @param map
    */
   public WikiSearch(Map<String, Integer> map) {
      this.map = map;
   }

   /**
    * Odnajduje trafność danego ciągu URL.
    *
    * @param url
    * @return
    */
   public Integer getRelevance(String url) {
      Integer relevance = map.get(url);
      return relevance==null ? 0: relevance;
   }

   /**
    * Wyświetla zawartość w porządku zgodnym z częstotliwością występowania słów.
    *
    * @param
    */
   private  void print() {
      List<Entry<String, Integer>> entries = sort();
      for (Entry<String, Integer> entry: entries) {
         System.out.println(entry);
      }
   }

   /**
    * Oblicza sumę zbiorów wyników dwóch wyszukiwań.
    *
    * @param that
    * @return Nowy obiekt WikiSearch.
    */
   public WikiSearch or(WikiSearch that) {
      // TODO: UZUPEŁNIJ TEN KOD!
      return null;
   }

   /**
    * Oblicza iloczyn zbiorów wyników dwóch wyszukiwań.
    *
    * @param that
    * @return Nowy obiekt WikiSearch.
    */
   public WikiSearch and(WikiSearch that) {
      // TODO: UZUPEŁNIJ TEN KOD!
      return null;
   }

   /**
    * Oblicza różnicę zbiorów wyników dwóch wyszukiwań.
    *
    * @param that
    * @return Nowy obiekt WikiSearch.
    */
   public WikiSearch minus(WikiSearch that) {
      // TODO: UZUPEŁNIJ TEN KOD!
      return null;
   }

   /**
    * Oblicza trafność wyszukiwania wielu słów.
    *
    * @param rel1: ocena trafności dla pierwszego wyszukiwania
    * @param rel2: ocena trafności dla drugiego wyszukiwania
    * @return
    */
   protected int totalRelevance(Integer rel1, Integer rel2) {
      // prosty przypadek na start: trafność jest sumą częstotliwości występowania słów.
      return rel1 + rel2;
   }

   /**
    * Sortuje wyniki według trafności.
    *
    * @return Lista wpisów z URL-ami i trafnością.
    */
   public List<Entry<String, Integer>> sort() {
      // TODO: UZUPEŁNIJ TEN KOD!
      return null;
   }


   /**
    * Przeprowadza wyszukiwanie i tworzy obiekt WikiSearch.
    *
    * @param term
    * @param index
    * @return
    */
   public static WikiSearch search(String term, JedisIndex index) {
      Map<String, Integer> map = index.getCounts(term);
      return new WikiSearch(map);
   }

   public static void main(String[] args) throws IOException {

      // utwórz JedisIndex
      Jedis jedis = JedisMaker.make();
      JedisIndex index = new JedisIndex(jedis);

      // wyszukaj pierwsze słowo
      String term1 = "java";
      System.out.println("Zapytanie: " + term1);
      WikiSearch search1 = search(term1, index);
      search1.print();

      //  wyszukaj drugie słowo
      String term2 = "programming";
      System.out.println("Zapytanie: " + term2);
      WikiSearch search2 = search(term2, index);
      search2.print();

      // oblicz iloczyn zbiorów wyników wyszukiwań
      System.out.println("Zapytanie: " + term1 + " I " + term2);
      WikiSearch intersection = search1.and(search2);
      intersection.print();
   }
}