// 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.googlesource.gerrit.plugins.reviewers.client;

import com.google.gerrit.client.rpc.NativeMap;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.client.ui.HighlightSuggestion;
import com.google.gerrit.plugin.client.rpc.RestApi;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.SuggestOracle;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;

/** A {@code SuggestOracle} for reviewers. */
public class ReviewerSuggestOracle extends SuggestOracle {
  private static final String ACCOUNT_KEY = "account";
  private static final String GROUP_KEY = "group";
  private static final String NAME_KEY = "name";
  private static final String EMAIL_KEY = "email";
  private static final String ACCOUNT_ID_KEY = "_account_id";

  private final int chars;
  private final String projectName;

  /**
   * @param chars minimum chars to start suggesting.
   * @param projectName the name of the project to check visibility
   */
  public ReviewerSuggestOracle(int chars, String projectName) {
    this.chars = chars;
    this.projectName = projectName;
  }

  @Override
  public boolean isDisplayStringHTML() {
    return true;
  }

  private class ReviewerSuggestion extends HighlightSuggestion {
    private final String name;

    ReviewerSuggestion(String query, String groupName) {
      super(query, groupName + " (group)");
      this.name = groupName;
    }

    ReviewerSuggestion(String query, String fullname, String email, String accountId) {
      super(query, fullname + ((!email.isEmpty()) ? " <" + email + ">" : " (" + accountId + ")"));
      this.name = fullname;
    }

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

  @Override
  public void requestSuggestions(final Request req, final Callback done) {
    if (req.getQuery().length() < chars) {
      responseEmptySuggestion(req, done);
      return;
    }
    RestApi rest = new RestApi("/projects/").id(projectName).view("suggest_reviewers");
    rest.addParameter("q", req.getQuery());
    if (req.getLimit() > 0) {
      rest.addParameter("n", req.getLimit());
    }
    rest.get(
        new AsyncCallback<NativeMap<JavaScriptObject>>() {
          @Override
          public void onSuccess(NativeMap<JavaScriptObject> result) {
            List<String> keys0 = result.sortedKeys();
            List<Suggestion> suggestions = new ArrayList<>(keys0.size());
            for (String key0 : keys0) {
              Set<String> keys1 = Natives.keys(result.get(key0));
              NativeMap<JavaScriptObject> map1 = result.get(key0).cast();
              for (String key1 : keys1) {
                NativeMap<JavaScriptObject> map2 = map1.get(key1).cast();
                if (ACCOUNT_KEY.equals(key1)) {
                  String name = map2.get(NAME_KEY).toString();
                  String email =
                      (map2.containsKey(EMAIL_KEY)) ? map2.get(EMAIL_KEY).toString() : "";
                  String accountId = map2.get(ACCOUNT_ID_KEY).toString();
                  suggestions.add(new ReviewerSuggestion(req.getQuery(), name, email, accountId));
                } else if (GROUP_KEY.equals(key1)) {
                  String name = map2.get(NAME_KEY).toString();
                  suggestions.add(new ReviewerSuggestion(req.getQuery(), name));
                }
              }
            }
            done.onSuggestionsReady(req, new Response(suggestions));
          }

          @Override
          public void onFailure(Throwable caught) {
            responseEmptySuggestion(req, done);
          }
        });
  }

  private static void responseEmptySuggestion(Request req, Callback done) {
    List<Suggestion> empty = Collections.emptyList();
    done.onSuggestionsReady(req, new Response(empty));
  }
}
