package com.kryptnostic.v2.search;

import java.util.Set;
import java.util.UUID;

import retrofit.http.Body;
import retrofit.http.POST;
import retrofit.http.Path;

public interface SearchApi {
    String CONTROLLER              = "/search";
    String OBJECT_ID               = "objectId";
    String OBJECT_ID_PATH          = "/{" + OBJECT_ID + "}";
    String COUNT                   = "count";
    String COUNT_PATH              = "/{" + COUNT + "}";

    /**
     * The returned set of UUIDs are object ids at which inverted index segments
     * are stored (encrypted by the AES master key for the channel)
     *
     * WARNING: The returned set of UUIDs are NOT object ids corresponding to
     * actual documents containing the search terms!
     *
     * To obtain the actual documents containing the search terms, the client
     * needs to:
     * (1) Load and decrypt the objects specified in the returned Set&lt;UUID&gt;
     *     to obtain inverted index segments
     * (2) Filter out those inverted index segments corresponding to terms that
     *     did not appear in the original set of search terms (this filtering
     *     is necessary due to potential hash collisions)
     * (3) Collect the object ids appear in the remaining inverted index
     *     segments; loading and decrypting these objets will result in the
     *     actual documents containing the search terms
     */
    @POST( CONTROLLER )
    Set<UUID> search( @Body Set<byte[]> fheEncryptedSearchTerms );

    /**
     * For a given inverted index segment corresponding to a particular object id
     * and search term, we compute the "address" at which to store the inverted
     * index segment as follows:
     * (1) Obtain an object search pair of the nearest ancestor that has an object
     *     search pair (in the case of kodex, this would be the channel)
     * (2) Use the client hash function, object search pair, and fhe encrypted search
     *     term to compute the "base address"
     * (3) Compute SHA256( base_address || j ), where j is the smallest natural number
     *     that has not been used in calculating addresses for the ancestor object
     *     from step (1)
     *
     * The result of step (3) is the "address" at which we store the inverted
     * index segment.
     *
     * The motivation for using distinct values of j is to avoid having multiple
     * inverted index segments corresponding to a particular search term getting
     * stored at the same address, because we want to avoid leaking information
     * about the distribution of term frequencies.
     *
     * The client and server must cooperate to prevent reusing values of j.  The
     * current segment count is the smallest value of j that's safe to use;
     * calling getAndAddSegmentCount with count = N will cause the server to
     * "reserve" the next N values of j and then return the current count.
     *
     * Note that the client shuffles its inverted index segments before computing
     * addresses, to partially protect against the case of a malicious server that
     * fails to increase its stored segment counts (and e.g. returns 0 every time
     * getAndAddSegmentCount is called, no matter what count the client passes in)
     */
    @POST( CONTROLLER + OBJECT_ID_PATH + COUNT_PATH )
    public int getAndAddSegmentCount( @Path( OBJECT_ID ) UUID objectId, @Path( COUNT ) int count );
}

@@ -50,34 +50,141 @@
 til.
-Set;%0Aimport java.util.UUID
+List;%0Aimport java.util.Map;%0Aimport java.util.Set;%0Aimport java.util.UUID;%0A%0Aimport com.kryptnostic.v2.storage.models.VersionedObjectKey
 ;%0A%0Ai
@@ -578,152 +578,66 @@
 The 
-returned set of UUIDs are object ids at which inverted index segments%0A     * are stored (encrypted by the AES master key for the channel)%0A     *
+values of the returned map are lists of index segment ids;
 %0A   
@@ -653,23 +653,15 @@
 NG: 
-The returned se
+the lis
 t of
@@ -757,10 +757,157 @@
 term
-s
 !
+%0A     *%0A     * The keys correspond to the actual objects whose cryptoservices%0A     * should be used to decrypt the index segments after loading them
 %0A   
@@ -1066,32 +1066,12 @@
 the 
-returned Set&lt;UUID&gt;
+keys
 %0A   
@@ -1455,16 +1455,17 @@
 ese obje
+c
 ts will 
@@ -1569,16 +1569,40 @@
 ER )%0A   
+ Map%3CVersionedObjectKey,
  Set%3CUUI
@@ -1603,16 +1603,17 @@
 et%3CUUID%3E
+%3E
  search(
@@ -1619,18 +1619,19 @@
 ( @Body 
-Se
+Lis
 t%3Cbyte%5B%5D

Fix API so that it specifies which object's cryptoservice to use for decryption