// 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();
            String name =  map2.get(NAME_KEY).toString();
            if (ACCOUNT_KEY.equals(key1)) {
              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)) {
              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));
  }
}
