// Copyright (C) 2014 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.server.restapi.account;

import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.gerrit.entities.Account;
import com.google.gerrit.extensions.client.ListAccountsOption;
import com.google.gerrit.extensions.client.ListOption;
import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.extensions.common.AccountVisibility;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.extensions.restapi.TopLevelResource;
import com.google.gerrit.index.query.Predicate;
import com.google.gerrit.index.query.QueryParseException;
import com.google.gerrit.index.query.QueryResult;
import com.google.gerrit.server.account.AccountDirectory.FillOptions;
import com.google.gerrit.server.account.AccountInfoComparator;
import com.google.gerrit.server.account.AccountLoader;
import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.permissions.GlobalPermission;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.query.account.AccountPredicates;
import com.google.gerrit.server.query.account.AccountQueryBuilder;
import com.google.gerrit.server.query.account.AccountQueryProcessor;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.util.Collections;
import java.util.EnumSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.jgit.lib.Config;
import org.kohsuke.args4j.Option;

/**
 * REST endpoint to query accounts.
 *
 * <p>This REST endpoint handles {@code GET /accounts/} requests.
 *
 * <p>The account queries are parsed by {@link AccountQueryBuilder} and executed by {@link
 * AccountQueryProcessor}.
 */
public class QueryAccounts implements RestReadView<TopLevelResource> {
  private static final int MAX_SUGGEST_RESULTS = 100;

  private final PermissionBackend permissionBackend;
  private final AccountLoader.Factory accountLoaderFactory;
  private final AccountQueryBuilder queryBuilder;
  private final Provider<AccountQueryProcessor> queryProcessorProvider;
  private final boolean suggestConfig;
  private final int suggestFrom;

  private AccountLoader accountLoader;
  private boolean suggest;
  private Integer limit;
  private int suggestLimit = 10;
  private String query;
  private Integer start;
  private EnumSet<ListAccountsOption> options;

  @Option(name = "--suggest", metaVar = "SUGGEST", usage = "suggest users")
  public void setSuggest(boolean suggest) {
    this.suggest = suggest;
  }

  @Option(
      name = "--limit",
      aliases = {"-n"},
      metaVar = "CNT",
      usage = "maximum number of users to return")
  public void setLimit(int n) {
    this.limit = n;

    if (n < 0) {
      suggestLimit = 10;
    } else if (n == 0) {
      suggestLimit = MAX_SUGGEST_RESULTS;
    } else {
      suggestLimit = Math.min(n, MAX_SUGGEST_RESULTS);
    }
  }

  @Option(name = "-o", usage = "Output options per account")
  public void addOption(ListAccountsOption o) {
    options.add(o);
  }

  @Option(name = "-O", usage = "Output option flags, in hex")
  void setOptionFlagsHex(String hex) throws BadRequestException {
    options.addAll(ListOption.fromHexString(ListAccountsOption.class, hex));
  }

  @Option(
      name = "--query",
      aliases = {"-q"},
      metaVar = "QUERY",
      usage = "match users")
  public void setQuery(String query) {
    this.query = query;
  }

  @Option(
      name = "--start",
      aliases = {"-S"},
      metaVar = "CNT",
      usage = "Number of accounts to skip")
  public void setStart(int start) {
    this.start = start;
  }

  @Inject
  QueryAccounts(
      PermissionBackend permissionBackend,
      AccountLoader.Factory accountLoaderFactory,
      AccountQueryBuilder queryBuilder,
      Provider<AccountQueryProcessor> queryProcessorProvider,
      @GerritServerConfig Config cfg) {
    this.permissionBackend = permissionBackend;
    this.accountLoaderFactory = accountLoaderFactory;
    this.queryBuilder = queryBuilder;
    this.queryProcessorProvider = queryProcessorProvider;
    this.suggestFrom = cfg.getInt("suggest", null, "from", 0);
    this.options = EnumSet.noneOf(ListAccountsOption.class);

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

  @Override
  public Response<List<AccountInfo>> apply(TopLevelResource rsrc)
      throws RestApiException, PermissionBackendException {
    if (Strings.isNullOrEmpty(query)) {
      throw new BadRequestException("missing query field");
    }

    if (suggest && (!suggestConfig || query.length() < suggestFrom)) {
      return Response.ok(Collections.emptyList());
    }

    Set<FillOptions> fillOptions = EnumSet.of(FillOptions.ID);
    if (options.contains(ListAccountsOption.DETAILS)) {
      fillOptions.addAll(AccountLoader.DETAILED_OPTIONS);
    }
    boolean modifyAccountCapabilityChecked = false;
    if (options.contains(ListAccountsOption.ALL_EMAILS)) {
      permissionBackend.currentUser().check(GlobalPermission.MODIFY_ACCOUNT);
      modifyAccountCapabilityChecked = true;
      fillOptions.add(FillOptions.EMAIL);
      fillOptions.add(FillOptions.SECONDARY_EMAILS);
    }
    if (suggest) {
      fillOptions.addAll(AccountLoader.DETAILED_OPTIONS);
      fillOptions.add(FillOptions.EMAIL);

      if (modifyAccountCapabilityChecked) {
        fillOptions.add(FillOptions.SECONDARY_EMAILS);
      } else {
        if (permissionBackend.currentUser().test(GlobalPermission.MODIFY_ACCOUNT)) {
          fillOptions.add(FillOptions.SECONDARY_EMAILS);
        }
      }
    }
    accountLoader = accountLoaderFactory.create(fillOptions);

    AccountQueryProcessor queryProcessor = queryProcessorProvider.get();
    if (queryProcessor.isDisabled()) {
      throw new MethodNotAllowedException("query disabled");
    }

    if (limit != null) {
      queryProcessor.setUserProvidedLimit(limit);
    }

    if (start != null) {
      queryProcessor.setStart(start);
    }

    Map<Account.Id, AccountInfo> matches = new LinkedHashMap<>();
    try {
      Predicate<AccountState> queryPred;
      if (suggest) {
        queryPred = queryBuilder.defaultQuery(query);
        queryProcessor.setUserProvidedLimit(suggestLimit);
      } else {
        queryPred = queryBuilder.parse(query);
      }
      if (!AccountPredicates.hasActive(queryPred)) {
        // if neither 'is:active' nor 'is:inactive' appears in the query only
        // active accounts should be queried
        queryPred = AccountPredicates.andActive(queryPred);
      }
      QueryResult<AccountState> result = queryProcessor.query(queryPred);
      for (AccountState accountState : result.entities()) {
        Account.Id id = accountState.account().id();
        matches.put(id, accountLoader.get(id));
      }

      accountLoader.fill();

      List<AccountInfo> sorted =
          AccountInfoComparator.ORDER_NULLS_LAST.sortedCopy(matches.values());
      if (!sorted.isEmpty() && result.more()) {
        sorted.get(sorted.size() - 1)._moreAccounts = true;
      }
      return Response.ok(sorted);
    } catch (QueryParseException e) {
      if (suggest) {
        return Response.ok(ImmutableList.of());
      }
      throw new BadRequestException(e.getMessage());
    }
  }
}
