/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.devrel.cluestick.searchservice;

import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.devrel.cluestick.studioclient.Symbol;

import com.appspot.cluestick_server.search.Search;
import com.appspot.cluestick_server.search.model.EventReq;
import com.appspot.cluestick_server.search.model.Result;
import com.appspot.cluestick_server.search.model.SearchResponse;
import com.intellij.openapi.diagnostic.Logger;

import org.jetbrains.annotations.Nullable;

import java.io.IOException;
import java.util.List;

/**
 * Plugin service to make search queries to Cluestick server.
 */
public class CluestickSearch {
  private static final Logger LOG =
      Logger.getInstance("#com.google.devrel.cluestick.searchservice.CluestickSearch");
  public static final String DEFAULT_USER_AGENT = "cluestick search";

  private final Search searchService;
  private String sessionId;

  public CluestickSearch() {
    searchService = new Search(new NetHttpTransport(), new JacksonFactory(), null);
  }

  public CluestickSearch(HttpTransport transport, JsonFactory jsonFactory) {
    searchService = new Search(transport, jsonFactory, null);
  }

  /**
   * Logs an event to the Cluestick service.
   *
   * @param action The string action, e.g. "copy".
   * @param resultKey The result being operated on, if any.
   * @param signal Either a positive or negative signal, e.g. for code result quality.
   */
  public void logEvent(@Nullable String action, @Nullable String resultKey, int signal) {
    EventReq event = new EventReq();
    event.setAction(action);
    event.setResultKey(resultKey);
    event.setSignal(signal);
    event.setSignal(event.getSignal().intValue() + signal);
    try {
      LOG.info("Logging event: " + event);
      Search.Event request = searchService.event(event);
      request.execute();  // no useful response type
    } catch (IOException e) {
      LOG.info("Log error: " + e);
    }
  }

  /**
   * Performs a blocking search to Cluestick service.
   *
   * @param symbol The symbol to search for.
   * @return The results found on Cluestick.
   * @throws IOException on a network error
   */
  public List<Result> performSearch(Symbol symbol, @Nullable String userAgent) throws IOException {
    Search.SearchOperation request = searchService.search();
    request.setSessionId(sessionId);
    request.setSymbol(symbol.symbolName);
    request.setPackage(symbol.packageName);
    // Assume lang is always java for now
    request.setLang("java");
    // TODO(thoroogod): For now, request all contents of result files. This may not be actually
    // that practical in terms of bandwidth.
    request.setAllContext(true);
    if (userAgent == null) {
      request.setUserAgent(userAgent);
    } else {
      request.setUserAgent(DEFAULT_USER_AGENT);
    }

    SearchResponse response = request.execute();
    if (response.getSessionId() != null) {
      // Save any server-hinted session ID.
      sessionId = response.getSessionId();
      LOG.info("Using updated sessionId: " + sessionId);
    }
    return response.getResults();
  }

}
