// Copyright (C) 2008 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.httpd.rpc;

import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.data.AccountInfo;
import com.google.gerrit.common.data.GroupReference;
import com.google.gerrit.common.data.ReviewerInfo;
import com.google.gerrit.common.data.SuggestService;
import com.google.gerrit.common.errors.NoSuchGroupException;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountExternalId;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.AccountControl;
import com.google.gerrit.server.account.AccountVisibility;
import com.google.gerrit.server.account.GroupBackend;
import com.google.gerrit.server.account.GroupMembers;
import com.google.gerrit.server.change.PostReviewers;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gwtjsonrpc.common.AsyncCallback;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;

import org.eclipse.jgit.lib.Config;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

class SuggestServiceImpl extends BaseServiceImplementation implements
    SuggestService {
  private static final String MAX_SUFFIX = "\u9fa5";

  private final Provider<ReviewDb> reviewDbProvider;
  private final AccountCache accountCache;
  private final GroupMembers.Factory groupMembersFactory;
  private final IdentifiedUser.GenericFactory identifiedUserFactory;
  private final AccountControl.Factory accountControlFactory;
  private final ChangeControl.Factory changeControlFactory;
  private final ProjectControl.Factory projectControlFactory;
  private final Config cfg;
  private final GroupBackend groupBackend;
  private final boolean suggestAccounts;

  @Inject
  SuggestServiceImpl(final Provider<ReviewDb> schema,
      final AccountCache accountCache,
      final GroupMembers.Factory groupMembersFactory,
      final Provider<CurrentUser> currentUser,
      final IdentifiedUser.GenericFactory identifiedUserFactory,
      final AccountControl.Factory accountControlFactory,
      final ChangeControl.Factory changeControlFactory,
      final ProjectControl.Factory projectControlFactory,
      @GerritServerConfig final Config cfg, final GroupBackend groupBackend) {
    super(schema, currentUser);
    this.reviewDbProvider = schema;
    this.accountCache = accountCache;
    this.groupMembersFactory = groupMembersFactory;
    this.identifiedUserFactory = identifiedUserFactory;
    this.accountControlFactory = accountControlFactory;
    this.changeControlFactory = changeControlFactory;
    this.projectControlFactory = projectControlFactory;
    this.cfg = cfg;
    this.groupBackend = groupBackend;

    if ("OFF".equals(cfg.getString("suggest", null, "accounts"))) {
      this.suggestAccounts = false;
    } else {
      boolean suggestAccounts;
      try {
        AccountVisibility av =
            cfg.getEnum("suggest", null, "accounts", AccountVisibility.ALL);
        suggestAccounts = (av != AccountVisibility.NONE);
      } catch (IllegalArgumentException err) {
        suggestAccounts = cfg.getBoolean("suggest", null, "accounts", true);
      }
      this.suggestAccounts = suggestAccounts;
    }
  }

  private interface VisibilityControl {
    boolean isVisible(Account account) throws OrmException;
  }

  public void suggestAccount(final String query, final Boolean active,
      final int limit, final AsyncCallback<List<AccountInfo>> callback) {
    run(callback, new Action<List<AccountInfo>>() {
      public List<AccountInfo> run(final ReviewDb db) throws OrmException {
        return suggestAccount(db, query, active, limit, new VisibilityControl() {
          @Override
          public boolean isVisible(Account account) throws OrmException {
            return accountControlFactory.get().canSee(account);
          }
        });
      }
    });
  }

  private List<AccountInfo> suggestAccount(final ReviewDb db,
      final String query, final Boolean active, final int limit,
      VisibilityControl visibilityControl)
      throws OrmException {
    if (!suggestAccounts) {
      return Collections.emptyList();
    }

    final String a = query;
    final String b = a + MAX_SUFFIX;
    final int max = 10;
    final int n = limit <= 0 ? max : Math.min(limit, max);

    final LinkedHashMap<Account.Id, AccountInfo> r =
        new LinkedHashMap<Account.Id, AccountInfo>();
    for (final Account p : db.accounts().suggestByFullName(a, b, n)) {
      addSuggestion(r, p, new AccountInfo(p), active, visibilityControl);
    }
    if (r.size() < n) {
      for (final Account p : db.accounts().suggestByPreferredEmail(a, b,
          n - r.size())) {
        addSuggestion(r, p, new AccountInfo(p), active, visibilityControl);
      }
    }
    if (r.size() < n) {
      for (final AccountExternalId e : db.accountExternalIds()
          .suggestByEmailAddress(a, b, n - r.size())) {
        if (!r.containsKey(e.getAccountId())) {
          final Account p = accountCache.get(e.getAccountId()).getAccount();
          final AccountInfo info = new AccountInfo(p);
          info.setPreferredEmail(e.getEmailAddress());
          addSuggestion(r, p, info, active, visibilityControl);
        }
      }
    }
    return new ArrayList<AccountInfo>(r.values());
  }

  private void addSuggestion(Map<Account.Id, AccountInfo> map, Account account,
      AccountInfo info, Boolean active, VisibilityControl visibilityControl)
      throws OrmException {
    if (map.containsKey(account.getId())) {
      return;
    }
    if (active != null && active != account.isActive()) {
      return;
    }
    if (visibilityControl.isVisible(account)) {
      map.put(account.getId(), info);
    }
  }

  public void suggestAccountGroup(final String query, final int limit,
      final AsyncCallback<List<GroupReference>> callback) {
    suggestAccountGroupForProject(null, query, limit, callback);
  }

  public void suggestAccountGroupForProject(final Project.NameKey project,
      final String query, final int limit,
      final AsyncCallback<List<GroupReference>> callback) {
    run(callback, new Action<List<GroupReference>>() {
      public List<GroupReference> run(final ReviewDb db) {
        ProjectControl projectControl = null;
        if (project != null) {
          try {
            projectControl = projectControlFactory.controlFor(project);
          } catch (NoSuchProjectException e) {
            return Collections.emptyList();
          }
        }
        return suggestAccountGroup(projectControl, query, limit);
      }
    });
  }

  private List<GroupReference> suggestAccountGroup(
      @Nullable final ProjectControl projectControl, final String query, final int limit) {
    return Lists.newArrayList(Iterables.limit(
        groupBackend.suggest(query, projectControl),
        limit <= 0 ? 10 : Math.min(limit, 10)));
  }

  @Override
  public void suggestReviewer(Project.NameKey project, String query, int limit,
      AsyncCallback<List<ReviewerInfo>> callback) {
    // The RPC is deprecated, but return an empty list for RPC API compatibility.
    callback.onSuccess(Collections.<ReviewerInfo>emptyList());
  }

  @Override
  public void suggestChangeReviewer(final Change.Id change,
      final String query, final int limit,
      final AsyncCallback<List<ReviewerInfo>> callback) {
    run(callback, new Action<List<ReviewerInfo>>() {
      public List<ReviewerInfo> run(final ReviewDb db)
          throws OrmException, Failure {
        final ChangeControl changeControl;
        try {
          changeControl = changeControlFactory.controlFor(change);
        } catch (NoSuchChangeException e) {
          return Collections.emptyList();
        }

        VisibilityControl visibilityControl;
        if (changeControl.getRefControl().isVisibleByRegisteredUsers()) {
          visibilityControl = new VisibilityControl() {
            @Override
            public boolean isVisible(Account account) throws OrmException {
              return true;
            }
          };
        } else {
          visibilityControl = new VisibilityControl() {
            @Override
            public boolean isVisible(Account account) throws OrmException {
              IdentifiedUser who =
                  identifiedUserFactory.create(reviewDbProvider, account.getId());
              // we can't use changeControl directly as it won't suggest reviewers
              // to drafts
              return changeControl.forUser(who).isRefVisible();
            }
          };
        }

        final List<AccountInfo> suggestedAccounts =
            suggestAccount(db, query, Boolean.TRUE, limit, visibilityControl);
        final List<ReviewerInfo> reviewer =
            new ArrayList<ReviewerInfo>(suggestedAccounts.size());
        for (final AccountInfo a : suggestedAccounts) {
          reviewer.add(new ReviewerInfo(a));
        }
        final List<GroupReference> suggestedAccountGroups =
            suggestAccountGroup(changeControl.getProjectControl(), query, limit);
        for (final GroupReference g : suggestedAccountGroups) {
          if (suggestGroupAsReviewer(changeControl.getProject().getNameKey(), g)) {
            reviewer.add(new ReviewerInfo(g));
          }
        }

        Collections.sort(reviewer);
        if (reviewer.size() <= limit) {
          return reviewer;
        } else {
          return reviewer.subList(0, limit);
        }
      }
    });
  }

  private boolean suggestGroupAsReviewer(final Project.NameKey project,
      final GroupReference group) throws OrmException, Failure {
    if (!PostReviewers.isLegalReviewerGroup(group.getUUID())) {
      return false;
    }

    try {
      final Set<Account> members = groupMembersFactory.create(getCurrentUser())
          .listAccounts(group.getUUID(), project);

      if (members.isEmpty()) {
        return false;
      }

      final int maxAllowed =
          cfg.getInt("addreviewer", "maxAllowed",
              PostReviewers.DEFAULT_MAX_REVIEWERS);
      if (maxAllowed > 0 && members.size() > maxAllowed) {
        return false;
      }
    } catch (NoSuchGroupException e) {
      return false;
    } catch (NoSuchProjectException e) {
      return false;
    } catch (IOException e) {
      throw new Failure(e);
    }

    return true;
  }
}
