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

import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.entities.AccessSection;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.Permission;
import com.google.gerrit.entities.PermissionRule;
import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.annotations.CapabilityScope;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.extensions.common.GroupInfo;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AccountResolver;
import com.google.gerrit.server.account.AccountResource;
import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.git.meta.MetaDataUpdate;
import com.google.gerrit.server.project.ProjectConfig;
import com.google.gerrit.server.restapi.account.GetGroups;
import com.google.gerrit.sshd.CommandMetaData;
import com.google.gerrit.sshd.SshCommand;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;

@RequiresCapability(value = GlobalCapability.ADMINISTRATE_SERVER, scope = CapabilityScope.CORE)
@CommandMetaData(
    name = "show-repo-account-access",
    description = "Displays user's access on a specific repository")
public final class ShowRepoAccountAccessCommand extends SshCommand {

  @Argument(usage = "project to show access for?")
  private String projectName = "";

  @Option(
      name = "--user",
      usage =
          "User information to find: LastName,\\ Firstname,  email@address.com, account id or an user name. "
              + "Be sure to double-escape spaces, for example: \"show-repo-account-access All-Projects --user Last,\\\\ First\"")
  private String name = "";

  @Option(name = "-w", usage = "display without line width truncation")
  private boolean wide;

  @Inject
  ShowRepoAccountAccessCommand(
      MetaDataUpdate.Server metaDataUpdateFactory,
      Provider<GetGroups> accountGetGroups,
      AccountResolver accountResolver,
      IdentifiedUser.GenericFactory userFactory,
      ProjectConfig.Factory projectConfigFactory) {
    this.metaDataUpdateFactory = metaDataUpdateFactory;
    this.accountGetGroups = accountGetGroups;
    this.accountResolver = accountResolver;
    this.userFactory = userFactory;
    this.projectConfigFactory = projectConfigFactory;
  }

  private final MetaDataUpdate.Server metaDataUpdateFactory;
  private final AccountResolver accountResolver;
  private final Provider<GetGroups> accountGetGroups;
  private final IdentifiedUser.GenericFactory userFactory;
  private final ProjectConfig.Factory projectConfigFactory;
  private int columns = 80;
  private int permissionGroupWidth;

  @Override
  public void run() throws UnloggedFailure, Failure, Exception {
    AccountState account;
    String sectionNameFormatter = "  %-25s\n";
    String ruleNameFormatter = "    %-15s\n ";
    String permissionNameFormatter = "      %5s %9s %s\n";

    Boolean userHasPermissionsInSection = false;
    Boolean userHasPermissionsInProject = false;

    if (projectName.isEmpty()) {
      throw new UnloggedFailure(1, "Please specify a project to show access for");
    }

    if (name.isEmpty()) {
      throw new UnloggedFailure(
          1,
          "You need to tell me who to find:  LastName,\\\\ Firstname, email@address.com, account id or an user name.  "
              + "Be sure to double-escape spaces, for example: \"show-repo-account-access All-Projects --user Last,\\\\ First\"");
    }
    Set<Account.Id> idList = accountResolver.resolve(name).asIdSet();
    if (idList.isEmpty()) {
      throw new UnloggedFailure(
          1,
          "No accounts found for your query: \""
              + name
              + "\""
              + " Tip: Try double-escaping spaces, for example: \"--user Last,\\\\ First\"");
    }

    Project.NameKey nameKey = Project.nameKey(projectName);

    try {
      MetaDataUpdate md = metaDataUpdateFactory.create(nameKey);
      ProjectConfig config;
      config = projectConfigFactory.read(md);

      permissionGroupWidth = wide ? Integer.MAX_VALUE : columns - 9 - 5 - 9;

      for (Account.Id id : idList) {
        userHasPermissionsInProject = false;
        account = accountResolver.resolve(id.toString()).asUnique();
        stdout.println("Full name:         " + account.account().fullName());
        // Need to know what groups the user is in. This is not a great
        // solution, but it does work.
        List<GroupInfo> groupInfos =
            accountGetGroups.get().apply(new AccountResource(userFactory.create(id))).value();
        HashSet<String> groupHash = new HashSet<>();

        for (GroupInfo groupInfo : groupInfos) {
          groupHash.add(groupInfo.name);
        }

        for (AccessSection accessSection : config.getAccessSections()) {
          StringBuilder sb = new StringBuilder();
          sb.append((String.format(sectionNameFormatter, accessSection.getName().toString())));
          // This is a solution to prevent displaying a section heading unless
          // the user has permissions for it
          // not the best solution, but I haven't been able to find
          // "Is user a member of this group" based on the information I have
          // in a more efficient manner yet.
          userHasPermissionsInSection = false;
          for (Permission permission : accessSection.getPermissions()) {

            for (PermissionRule rule : permission.getRules()) {

              if (groupHash.contains(rule.getGroup().getName())) {
                sb.append(String.format(ruleNameFormatter, permission.getName()));
                sb.append(
                    String.format(
                        permissionNameFormatter,
                        (rule.getMin() != rule.getMax())
                            ? "" + rule.getMin() + " " + rule.getMax()
                            : rule.getAction(),
                        (permission.getExclusiveGroup() ? "EXCLUSIVE" : ""),
                        format(rule.getGroup().getName())));
                userHasPermissionsInSection = true;
              }
            }
          }

          if (userHasPermissionsInSection) {
            stdout.print(sb.toString());

            userHasPermissionsInProject = true;
          }
        }

        if (!userHasPermissionsInProject) {
          stdout.println("  No access found for this user on this repository");
        }
      }
    } catch (RepositoryNotFoundException e) {
      throw new UnloggedFailure(1, "Repository not found");
    }
  }

  private String format(String s) {
    if (s.length() < permissionGroupWidth) {
      return s;
    }
    return s.substring(0, permissionGroupWidth);
  }
}
