// Copyright (C) 2012 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.gerrit.client;

import com.google.gerrit.client.ui.AccountGroupSuggestOracle;
import com.google.gerrit.client.ui.AccountSuggestOracle;
import com.google.gerrit.client.ui.ProjectNameSuggestOracle;
import com.google.gwt.user.client.ui.SuggestOracle;
import com.google.gwtexpui.safehtml.client.HighlightSuggestOracle;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.TreeSet;

public class SearchSuggestOracle extends HighlightSuggestOracle {
  private static final List<ParamSuggester> paramSuggester =
      Arrays.asList(
          new ParamSuggester(
              Arrays.asList("project:", "p:", "parentproject:"), new ProjectNameSuggestOracle()),
          new ParamSuggester(
              Arrays.asList(
                  "owner:",
                  "o:",
                  "reviewer:",
                  "r:",
                  "commentby:",
                  "reviewedby:",
                  "author:",
                  "committer:",
                  "from:",
                  "assignee:",
                  "cc:"),
              new AccountSuggestOracle() {
                @Override
                public void onRequestSuggestions(Request request, Callback done) {
                  super.onRequestSuggestions(
                      request,
                      new Callback() {
                        @Override
                        public void onSuggestionsReady(final Request request, Response response) {
                          if ("self".startsWith(request.getQuery())) {
                            final ArrayList<SuggestOracle.Suggestion> r =
                                new ArrayList<>(response.getSuggestions().size() + 1);
                            r.add(
                                new SuggestOracle.Suggestion() {
                                  @Override
                                  public String getDisplayString() {
                                    return getReplacementString();
                                  }

                                  @Override
                                  public String getReplacementString() {
                                    return "self";
                                  }
                                });
                            r.addAll(response.getSuggestions());
                            response.setSuggestions(r);
                          }
                          done.onSuggestionsReady(request, response);
                        }
                      });
                }
              }),
          new ParamSuggester(
              Arrays.asList("ownerin:", "reviewerin:"), new AccountGroupSuggestOracle()));

  private static final TreeSet<String> suggestions = new TreeSet<>();

  static {
    suggestions.add("age:");
    suggestions.add("age:1week"); // Give an example age

    suggestions.add("change:");

    suggestions.add("owner:");
    suggestions.add("owner:self");
    suggestions.add("ownerin:");
    suggestions.add("author:");
    suggestions.add("committer:");
    suggestions.add("assignee:");

    suggestions.add("reviewer:");
    suggestions.add("reviewer:self");
    suggestions.add("reviewerin:");
    suggestions.add("reviewedby:");

    suggestions.add("commit:");
    suggestions.add("comment:");
    suggestions.add("message:");
    suggestions.add("commentby:");
    suggestions.add("from:");
    suggestions.add("file:");
    suggestions.add("conflicts:");
    suggestions.add("project:");
    suggestions.add("projects:");
    suggestions.add("parentproject:");
    suggestions.add("branch:");
    suggestions.add("topic:");
    suggestions.add("intopic:");
    suggestions.add("ref:");
    suggestions.add("tr:");
    suggestions.add("bug:");
    suggestions.add("label:");
    suggestions.add("query:");
    suggestions.add("has:");
    suggestions.add("has:draft");
    suggestions.add("has:edit");
    suggestions.add("has:star");
    suggestions.add("has:stars");
    suggestions.add("has:unresolved");
    suggestions.add("star:");

    suggestions.add("is:");
    suggestions.add("is:starred");
    suggestions.add("is:watched");
    suggestions.add("is:reviewed");
    suggestions.add("is:owner");
    suggestions.add("is:reviewer");
    suggestions.add("is:open");
    suggestions.add("is:pending");
    suggestions.add("is:private");
    suggestions.add("is:closed");
    suggestions.add("is:merged");
    suggestions.add("is:abandoned");
    suggestions.add("is:mergeable");
    suggestions.add("is:ignored");
    suggestions.add("is:wip");
    suggestions.add("is:assigned");
    suggestions.add("is:submittable");

    suggestions.add("status:");
    suggestions.add("status:open");
    suggestions.add("status:pending");
    suggestions.add("status:reviewed");
    suggestions.add("status:closed");
    suggestions.add("status:merged");
    suggestions.add("status:abandoned");

    suggestions.add("added:");
    suggestions.add("deleted:");
    suggestions.add("delta:");
    suggestions.add("size:");

    suggestions.add("unresolved:");

    suggestions.add("revertof:");

    if (Gerrit.isNoteDbEnabled()) {
      suggestions.add("cc:");
      suggestions.add("hashtag:");
    }

    suggestions.add("is:assigned");
    suggestions.add("is:unassigned");
    suggestions.add("assignee:");

    suggestions.add("AND");
    suggestions.add("OR");
    suggestions.add("NOT");
  }

  @Override
  public void requestDefaultSuggestions(Request request, Callback done) {
    final ArrayList<SearchSuggestion> r = new ArrayList<>();
    // No text - show some default suggestions.
    r.add(new SearchSuggestion("status:open", "status:open"));
    r.add(new SearchSuggestion("age:1week", "age:1week"));
    if (Gerrit.isSignedIn()) {
      r.add(new SearchSuggestion("owner:self", "owner:self"));
    }
    done.onSuggestionsReady(request, new Response(r));
  }

  @Override
  protected void onRequestSuggestions(Request request, Callback done) {
    final String query = request.getQuery();

    final String lastWord = getLastWord(query);
    if (lastWord == null) {
      // Starting a new word - don't show suggestions yet.
      done.onSuggestionsReady(request, null);
      return;
    }

    for (ParamSuggester ps : paramSuggester) {
      if (ps.applicable(lastWord)) {
        ps.suggest(lastWord, request, done);
        return;
      }
    }

    final ArrayList<SearchSuggestion> r = new ArrayList<>();
    for (String suggestion : suggestions.tailSet(lastWord)) {
      if ((lastWord.length() < suggestion.length()) && suggestion.startsWith(lastWord)) {
        if (suggestion.contains("self") && !Gerrit.isSignedIn()) {
          continue;
        }
        r.add(new SearchSuggestion(suggestion, query + suggestion.substring(lastWord.length())));
      }
    }
    done.onSuggestionsReady(request, new Response(r));
  }

  private String getLastWord(String query) {
    final int lastSpace = query.lastIndexOf(' ');
    if (lastSpace == query.length() - 1) {
      return null;
    }
    if (lastSpace == -1) {
      return query;
    }
    return query.substring(lastSpace + 1);
  }

  @Override
  protected String getQueryPattern(String query) {
    return super.getQueryPattern(getLastWord(query));
  }

  @Override
  protected boolean isHTML() {
    return true;
  }

  private static class SearchSuggestion implements SuggestOracle.Suggestion {
    private final String suggestion;
    private final String fullQuery;

    SearchSuggestion(String suggestion, String fullQuery) {
      this.suggestion = suggestion;
      // Add a space to the query if it is a complete operation (e.g.
      // "status:open") so the user can keep on typing.
      this.fullQuery = fullQuery.endsWith(":") ? fullQuery : fullQuery + " ";
    }

    @Override
    public String getDisplayString() {
      return suggestion;
    }

    @Override
    public String getReplacementString() {
      return fullQuery;
    }
  }

  private static class ParamSuggester {
    private final List<String> operators;
    private final SuggestOracle parameterSuggestionOracle;

    ParamSuggester(List<String> operators, SuggestOracle parameterSuggestionOracle) {
      this.operators = operators;
      this.parameterSuggestionOracle = parameterSuggestionOracle;
    }

    boolean applicable(String query) {
      final String operator = getApplicableOperator(query, operators);
      return operator != null && query.length() > operator.length();
    }

    private String getApplicableOperator(String lastWord, List<String> operators) {
      for (String operator : operators) {
        if (lastWord.startsWith(operator)) {
          return operator;
        }
      }
      return null;
    }

    void suggest(String lastWord, Request request, Callback done) {
      final String operator = getApplicableOperator(lastWord, operators);
      parameterSuggestionOracle.requestSuggestions(
          new Request(lastWord.substring(operator.length()), request.getLimit()),
          new Callback() {
            @Override
            public void onSuggestionsReady(Request req, Response response) {
              final String query = request.getQuery();
              final List<SearchSuggestOracle.Suggestion> r =
                  new ArrayList<>(response.getSuggestions().size());
              for (SearchSuggestOracle.Suggestion s : response.getSuggestions()) {
                r.add(
                    new SearchSuggestion(
                        s.getDisplayString(),
                        query.substring(0, query.length() - lastWord.length())
                            + operator
                            + quoteIfNeeded(s.getReplacementString())));
              }
              done.onSuggestionsReady(request, new Response(r));
            }

            private String quoteIfNeeded(String s) {
              if (!s.matches("^\\S*$")) {
                return "\"" + s + "\"";
              }
              return s;
            }
          });
    }
  }
}
