# -*- coding: utf-8 -*-
"""
This software is licensed under the License (MIT) located at
https://github.com/ephreal/rollbot/Licence

Please see the license for any restrictions or rights granted to you by the
License.
"""

from nltk.corpus import stopwords

import json
import nltk


class IndexSearch():
    """
    Searches through the index generated by an indexer for matches to words.
    """

    def __init__(self, index_path="audio/song_index.json"):
        self.index = index_path

    def search(self, tokens, search_type=None):
        """
        Searches for matching tokens inside the index file. If none match,
        returns and empty list. If any match, it calls self.rank_results() to
        rank the results for ease of use.

        If search_type is set, it will attempt to search for that data instead
        of the default data in the index (ie: search for authors rather than
        songs)

        tokens: string
        search_type: string
            -> [] or songs[string]
        """
        results = []
        # Remove stopwords from the tokens to search for
        stop_words = set(stopwords.words('english'))
        tokens = nltk.tokenize.word_tokenize(tokens)
        tokens = [t.lower() for t in tokens if t not in stop_words]

        # load the index
        with open(self.index, 'r') as r:
            index = json.loads(r.read())

        for token in tokens:
            try:
                results.extend(self.create_result(index[token]))
            except KeyError:
                continue

        results = self.rank_results(results)

        return results

    def rank_results(self, results):
        """
        Ranks a list of results.

        results: {token: [results]}
            -> results(string)
        """

        sorted_results = []

        while results:
            to_pop = []
            result = results[0]
            results = results[1:]

            for i in range(len(results)):
                if result == results[i]:
                    to_pop.append(i)
                    result.relevance += 1
            if results:
                to_pop.sort(reverse=True)
                for i in to_pop:
                    results.pop(i)
            sorted_results.append(result)

        sorted_results.sort(reverse=True)
        return sorted_results

    def create_result(self, item):
        """
        Creates a result object to add to the results
        """
        results = []
        for key in list(item.keys()):
            result = Result(key, item[key])
            results.append(result)
        return results


class Result():
    """
    A class to store results into.
    """
    def __init__(self, name, path, relevance=1):
        self.name = name
        self.path = path
        self.relevance = relevance

    def __gt__(self, result2):
        return self.relevance > result2.relevance

    def __eq__(self, result2):
        return self.path == result2.path
