module.exports = lookup

var _ = require('lodash'),
    Promise = require('bluebird')

var debug = console.log

/**
 *
 * replace special elements with their possible values in the index.
 *       e.g., replaces com.google.* with com.google.android.maps.MapView and
 *          com.google.android.youtube.player.YouTubeThumbnailView.
 *       Replaces *.android.maps.MapView with com.google.android.maps.MapView  and
 *          com.google.android.gms.maps.MapView
 *
 * @param index the index that contains all the elements.
 * @param words the list of words in the query.
 * @returns a new array of unique values after replacing the special elements.
 * @private
 */
function _resolveWords(index, words) {
    var result = []
    words.forEach(function (word) {
        if (word.indexOf('*') == word.length - 1) {
            result.push(_.filter(Object.keys(index), function (w) {
                return _.startsWith(w, word.split('*')[0])
            }));
        }
        else if (word.indexOf('*') == 0) {
            result.push(_.filter(Object.keys(index), function (w) {
                return _.endsWith(w, word.split('*')[1])
            }));
        }
        else {
            return result.push(word)
        }
    });

    return _.unique(_.flattenDeep(result));

}

// search in the index for docs matching the given query
// return a list of ids
function lookup(index, query) {

    var words = _resolveWords(index, query.words);

    // e.g.,
    //
    // index = {
    //     LinearLayout: [{
    //         id: 1,
    //         count: 3
    //     }],
    //     ImageButton: [{
    //         id: 1,
    //         count: 4
    //     }, {
    //         id: 2,
    //         count: 2
    //     }]
    // }
    //
    // 
    // query = {
    //     words: ['ImageButton', 'LinearLayout']
    // }

    var idsForAllWords = _.map(words, function (word) {

        // get the ids of the list of docs containing this word
        var ids = _.pluck(index[word], 'id')
        // debug(ids)
        return ids

    })

    // debug(idsForAllWords)
    var results = _.reduce(idsForAllWords, function (intersectionOfAll, idsPerWord, index) {
        // debug(intersectionOfAll, idsPerWord, index)
        return _.intersection(intersectionOfAll, idsPerWord)
    })

    // debug(results)
    return new Promise(function (resolve, reject) {
        resolve(results)
    })
    // return results
}
@@ -123,32 +123,56 @@
 replace special 
+ wildcard characters in 
 elements with th
@@ -190,16 +190,24 @@
 e values
+%0A *     
  in the 
@@ -212,25 +212,16 @@
 e index.
-%0A *      
  e.g., r
@@ -606,19 +606,128 @@
 rns 
-a new
+%7BcustomWords: Array, words: Array%7D An object with two properties,%0A * where the customWords property contains an
  array
+%0A *
  of 
@@ -772,98 +772,430 @@
 ial 
-elements.%0A * @private%0A */%0Afunction _resolveWords(index, words) %7B%0A    var result = %5B%5D%0A    w
+wildcard characters (e.g., *),%0A * and the words property contains an array of the words with no meta characters.%0A * @private%0A */%0Afunction _resolveWords(index, words) %7B%0A    var resultSpecialWords = %5B%5D%0A    var resultWords = _.filter(words, function (w) %7B%0A        return (w.indexOf('*') === -1 && (w != '?'))%0A    %7D)%0A    var specialWords = _.filter(words, function (w) %7B%0A        return w.indexOf('*') != -1%0A    %7D)%0A    specialW
 ords
@@ -1283,32 +1283,44 @@
           result
+SpecialWords
 .push(_.filter(O
@@ -1496,24 +1496,36 @@
       result
+SpecialWords
 .push(_.filt
@@ -1654,119 +1654,145 @@
     
-    else %7B%0A            return result.push(word)%0A        %7D%0A    %7D);%0A%0A    return _.unique(_.flattenDeep(result));%0A
+%7D);%0A    resultSpecialWords = _.unique(_.flattenDeep(resultSpecialWords))%0A    return %7BcustomWords: resultSpecialWords, words: resultWords%7D
 %0A%7D%0A%0A
@@ -2343,27 +2343,24 @@
   var idsFor
-All
 Words = _.ma
@@ -2362,24 +2362,30 @@
  _.map(words
+.words
 , function (
@@ -2510,28 +2510,214 @@
         
-// debug(ids
+return ids%0A%0A    %7D)%0A    var idsForCustomWords = _.map(words.customWords, function (word) %7B%0A%0A        // get the ids of the list of docs containing this word%0A        var ids = _.pluck(index%5Bword%5D, 'id'
 )%0A      
@@ -2782,16 +2782,24 @@
  results
+ForWords
  = _.red
@@ -2804,27 +2804,24 @@
 educe(idsFor
-All
 Words, funct
@@ -2981,32 +2981,229 @@
 erWord)%0A    %7D)%0A%0A
+    var resultsForCustomWords = _.unique(_.flattenDeep(idsForCustomWords))%0A%0A    var results = _.union(resultsForWords, resultsForCustomWords).sort(function (a, b) %7B%0A        return a - b;%0A    %7D);%0A%0A%0A
     // debug(res

fix id lookups