package oasis.web.applications;

import java.util.Collections;
import java.util.Set;

import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Optional;
import com.google.common.base.Predicates;
import com.google.common.collect.FluentIterable;
import com.ibm.icu.util.ULocale;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;

import oasis.model.applications.v2.CatalogEntry;
import oasis.model.applications.v2.CatalogEntryRepository;
import oasis.model.applications.v2.ImmutableCatalogEntryRepository;

@Path("/m/search")
@Api(value = "market-search", description = "Searches the market catalog")
public class MarketSearchEndpoint {
  private static final Logger logger = LoggerFactory.getLogger(MarketSearchEndpoint.class);

  @Inject CatalogEntryRepository catalogEntryRepository;

  @GET
  @Produces(MediaType.APPLICATION_JSON)
  @ApiOperation(
      value = "Searches the market catalog",
      response = CatalogEntry.class,
      responseContainer = "Array"
  )
  public Response search(
      @Nullable @QueryParam("hl") final ULocale locale,
      @DefaultValue("0") @QueryParam("start") int start,
      @DefaultValue("25") @QueryParam("limit") int limit,
      // TODO: handle full-text search
      // @Nullable @QueryParam("q") String query,
      @Nullable @QueryParam("territory_id") Set<String> territory_id,
      @Nullable @QueryParam("target_audience") Set<CatalogEntry.TargetAudience> target_audience,
      @Nullable @QueryParam("payment_option") Set<CatalogEntry.PaymentOption> payment_option,
      @Nullable @QueryParam("category_id") Set<String> category_id
  ) {
    // TODO: use ElasticSearch
    // TODO: add information about apps the user has already "bought"
    CatalogEntryRepository.SearchRequest request = ImmutableCatalogEntryRepository.SearchRequest.builder()
        .displayLocale(Optional.fromNullable(locale))
        .start(start)
        .limit(limit)
        .addAllTerritory_id(preProcessStr(territory_id))
        .addAllTarget_audience(preProcess(target_audience))
        .addAllPayment_option(preProcess(payment_option))
        .addAllCategory_id(preProcessStr(category_id))
        .build();
    return Response.ok()
        .entity(new GenericEntity<Iterable<CatalogEntry>>(
            catalogEntryRepository.search(request)
        ) {})
        .build();
  }

  private Iterable<String> preProcessStr(@Nullable Set<String> s) {
    if (s == null) {
      return Collections.emptySet();
    }
    return FluentIterable.from(s)
        .filter(Predicates.notNull())
        .filter(Predicates.not(Predicates.equalTo("")));
  }

  private <T extends Enum<T>> Iterable<T> preProcess(@Nullable Set<T> s) {
    if (s == null) {
      return Collections.emptySet();
    }
    return FluentIterable.from(s)
        .filter(Predicates.notNull());
  }
}

@@ -141,16 +141,45 @@
 Inject;%0A
+import javax.ws.rs.Consumes;%0A
 import j
@@ -222,18 +222,73 @@
 x.ws.rs.
-GE
+FormParam;%0Aimport javax.ws.rs.GET;%0Aimport javax.ws.rs.POS
 T;%0Aimpor
@@ -1071,136 +1071,81 @@
 g%22)%0A
-public class MarketSearchEndpoint %7B%0A  private static final Logger logger = LoggerFactory.getLogger(MarketSearchEndpoint.class);%0A
+@Produces(MediaType.APPLICATION_JSON)%0Apublic class MarketSearchEndpoint %7B
 %0A  @
@@ -1210,48 +1210,8 @@
 GET%0A
-  @Produces(MediaType.APPLICATION_JSON)%0A
   @A
@@ -1361,22 +1361,19 @@
 esponse 
-search
+get
 (%0A      
@@ -1403,14 +1403,8 @@
 hl%22)
- final
  ULo
@@ -1950,24 +1950,791 @@
 ry_id%0A  ) %7B%0A
+    return post(locale, start, limit, territory_id, target_audience, payment_option, category_id);%0A  %7D%0A%0A  @POST%0A  @Consumes(MediaType.APPLICATION_FORM_URLENCODED)%0A  public Response post(%0A      @Nullable @FormParam(%22hl%22) ULocale locale,%0A      @DefaultValue(%220%22) @FormParam(%22start%22) int start,%0A      @DefaultValue(%2225%22) @FormParam(%22limit%22) int limit,%0A      // TODO: handle full-text search%0A      // @Nullable @FormParam(%22q%22) String query,%0A      @Nullable @FormParam(%22territory_id%22) Set%3CString%3E territory_id,%0A      @Nullable @FormParam(%22target_audience%22) Set%3CCatalogEntry.TargetAudience%3E target_audience,%0A      @Nullable @FormParam(%22payment_option%22) Set%3CCatalogEntry.PaymentOption%3E payment_option,%0A      @Nullable @FormParam(%22category_id%22) Set%3CString%3E category_id%0A  ) %7B%0A
     // TODO:

Support POST on market search endpoint