// Copyright (C) 2009 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.project;

import static org.eclipse.jgit.lib.RefDatabase.ALL;

import com.google.common.collect.Lists;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.common.data.AccessSection;
import com.google.gerrit.common.data.Capable;
import com.google.gerrit.common.data.ContributorAgreement;
import com.google.gerrit.common.data.GroupReference;
import com.google.gerrit.common.data.LabelTypes;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.common.data.PermissionRule;
import com.google.gerrit.common.data.PermissionRule.Action;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.InternalUser;
import com.google.gerrit.server.config.CanonicalWebUrl;
import com.google.gerrit.server.config.GitReceivePackGroups;
import com.google.gerrit.server.config.GitUploadPackGroups;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.assistedinject.Assisted;

import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

/** Access control management for a user accessing a project's data. */
public class ProjectControl {
  public static final int VISIBLE = 1 << 0;
  public static final int OWNER = 1 << 1;

  private static final Logger log = LoggerFactory.getLogger(ProjectControl.class);

  public static class GenericFactory {
    private final ProjectCache projectCache;

    @Inject
    GenericFactory(final ProjectCache pc) {
      projectCache = pc;
    }

    public ProjectControl controlFor(Project.NameKey nameKey, CurrentUser user)
        throws NoSuchProjectException, IOException {
      final ProjectState p = projectCache.checkedGet(nameKey);
      if (p == null) {
        throw new NoSuchProjectException(nameKey);
      }
      return p.controlFor(user);
    }

    public ProjectControl validateFor(Project.NameKey nameKey, int need,
        CurrentUser user) throws NoSuchProjectException, IOException {
      final ProjectControl c = controlFor(nameKey, user);
      if ((need & VISIBLE) == VISIBLE && c.isVisible()) {
        return c;
      }
      if ((need & OWNER) == OWNER && c.isOwner()) {
        return c;
      }
      throw new NoSuchProjectException(nameKey);
    }
  }

  public static class Factory {
    private final Provider<PerRequestProjectControlCache> userCache;

    @Inject
    Factory(Provider<PerRequestProjectControlCache> uc) {
      userCache = uc;
    }

    public ProjectControl controlFor(final Project.NameKey nameKey)
        throws NoSuchProjectException {
      return userCache.get().get(nameKey);
    }

    public ProjectControl validateFor(final Project.NameKey nameKey)
        throws NoSuchProjectException {
      return validateFor(nameKey, VISIBLE);
    }

    public ProjectControl ownerFor(final Project.NameKey nameKey)
        throws NoSuchProjectException {
      return validateFor(nameKey, OWNER);
    }

    public ProjectControl validateFor(final Project.NameKey nameKey,
        final int need) throws NoSuchProjectException {
      final ProjectControl c = controlFor(nameKey);
      if ((need & VISIBLE) == VISIBLE && c.isVisible()) {
        return c;
      }
      if ((need & OWNER) == OWNER && c.isOwner()) {
        return c;
      }
      throw new NoSuchProjectException(nameKey);
    }
  }

  interface AssistedFactory {
    ProjectControl create(CurrentUser who, ProjectState ps);
  }

  private final Set<AccountGroup.UUID> uploadGroups;
  private final Set<AccountGroup.UUID> receiveGroups;

  private final String canonicalWebUrl;
  private final CurrentUser user;
  private final ProjectState state;
  private final GitRepositoryManager repoManager;
  private final PermissionCollection.Factory permissionFilter;
  private final Collection<ContributorAgreement> contributorAgreements;

  private List<SectionMatcher> allSections;
  private List<SectionMatcher> localSections;
  private LabelTypes labelTypes;
  private Map<String, RefControl> refControls;
  private Boolean declaredOwner;

  @Inject
  ProjectControl(@GitUploadPackGroups Set<AccountGroup.UUID> uploadGroups,
      @GitReceivePackGroups Set<AccountGroup.UUID> receiveGroups,
      final ProjectCache pc, final PermissionCollection.Factory permissionFilter,
      final GitRepositoryManager repoManager,
      @CanonicalWebUrl @Nullable final String canonicalWebUrl,
      @Assisted CurrentUser who, @Assisted ProjectState ps) {
    this.repoManager = repoManager;
    this.uploadGroups = uploadGroups;
    this.receiveGroups = receiveGroups;
    this.permissionFilter = permissionFilter;
    this.contributorAgreements = pc.getAllProjects().getConfig().getContributorAgreements();
    this.canonicalWebUrl = canonicalWebUrl;
    user = who;
    state = ps;
  }

  public ProjectControl forUser(CurrentUser who) {
    ProjectControl r = state.controlFor(who);
    // Not per-user, and reusing saves lookup time.
    r.allSections = allSections;
    return r;
  }

  public ChangeControl controlFor(final Change change) {
    return new ChangeControl(controlForRef(change.getDest()), change);
  }

  public RefControl controlForRef(Branch.NameKey ref) {
    return controlForRef(ref.get());
  }

  public RefControl controlForRef(String refName) {
    if (refControls == null) {
      refControls = new HashMap<String, RefControl>();
    }
    RefControl ctl = refControls.get(refName);
    if (ctl == null) {
      PermissionCollection relevant =
          permissionFilter.filter(access(), refName, user.getUserName());
      ctl = new RefControl(this, refName, relevant);
      refControls.put(refName, ctl);
    }
    return ctl;
  }

  public CurrentUser getCurrentUser() {
    return user;
  }

  public ProjectState getProjectState() {
    return state;
  }

  public Project getProject() {
    return state.getProject();
  }

  public LabelTypes getLabelTypes() {
    if (labelTypes == null) {
      labelTypes = state.getLabelTypes();
    }
    return labelTypes;
  }

  private boolean isHidden() {
    return getProject().getState().equals(Project.State.HIDDEN);
  }

  /** Can this user see this project exists? */
  public boolean isVisible() {
    return (user instanceof InternalUser
        || canPerformOnAnyRef(Permission.READ)) && !isHidden();
  }

  public boolean canAddRefs() {
    return (canPerformOnAnyRef(Permission.CREATE)
        || isOwnerAnyRef());
  }

  public boolean canUpload() {
    for (SectionMatcher matcher : access()) {
      AccessSection section = matcher.section;
      if (section.getName().startsWith("refs/for/")) {
        Permission permission = section.getPermission(Permission.PUSH);
        if (permission != null
            && controlForRef(section.getName()).canPerform(Permission.PUSH)) {
          return true;
        }
      }
    }
    return false;
  }

  /** Can this user see all the refs in this projects? */
  public boolean allRefsAreVisible() {
    return allRefsAreVisibleExcept(Collections.<String> emptySet());
  }

  public boolean allRefsAreVisibleExcept(Set<String> except) {
    return user instanceof InternalUser
        || canPerformOnAllRefs(Permission.READ, except);
  }

  /** Is this user a project owner? Ownership does not imply {@link #isVisible()} */
  public boolean isOwner() {
    return isDeclaredOwner()
      || user.getCapabilities().canAdministrateServer();
  }

  private boolean isDeclaredOwner() {
    if (declaredOwner == null) {
      declaredOwner = state.isOwner(user.getEffectiveGroups());
    }
    return declaredOwner;
  }

  /** Does this user have ownership on at least one reference name? */
  public boolean isOwnerAnyRef() {
    return canPerformOnAnyRef(Permission.OWNER)
        || user.getCapabilities().canAdministrateServer();
  }

  /** @return true if the user can upload to at least one reference */
  public Capable canPushToAtLeastOneRef() {
    if (! canPerformOnAnyRef(Permission.PUSH) &&
        ! canPerformOnAnyRef(Permission.PUSH_TAG)) {
      String pName = state.getProject().getName();
      return new Capable("Upload denied for project '" + pName + "'");
    }
    if (state.isUseContributorAgreements()) {
      return verifyActiveContributorAgreement();
    }
    return Capable.OK;
  }

  public Set<GroupReference> getAllGroups() {
    return getGroups(access());
  }

  public Set<GroupReference> getLocalGroups() {
    return getGroups(localAccess());
  }

  private static Set<GroupReference> getGroups(
      final List<SectionMatcher> sectionMatcherList) {
    final Set<GroupReference> all = new HashSet<GroupReference>();
    for (final SectionMatcher matcher : sectionMatcherList) {
      final AccessSection section = matcher.section;
      for (final Permission permission : section.getPermissions()) {
        for (final PermissionRule rule : permission.getRules()) {
          all.add(rule.getGroup());
        }
      }
    }
    return all;
  }

  private Capable verifyActiveContributorAgreement() {
    if (! (user.isIdentifiedUser())) {
      return new Capable("Must be logged in to verify Contributor Agreement");
    }
    final IdentifiedUser iUser = (IdentifiedUser) user;

    boolean hasContactInfo = !missing(iUser.getAccount().getFullName())
        && !missing(iUser.getAccount().getPreferredEmail())
        && iUser.getAccount().isContactFiled();

    List<AccountGroup.UUID> okGroupIds = Lists.newArrayList();
    List<AccountGroup.UUID> missingInfoGroupIds = Lists.newArrayList();
    for (ContributorAgreement ca : contributorAgreements) {
      List<AccountGroup.UUID> groupIds;
      if (hasContactInfo || !ca.isRequireContactInformation()) {
        groupIds = okGroupIds;
      } else {
        groupIds = missingInfoGroupIds;
      }

      for (PermissionRule rule : ca.getAccepted()) {
        if ((rule.getAction() == Action.ALLOW) && (rule.getGroup() != null)
            && (rule.getGroup().getUUID() != null)) {
          groupIds.add(new AccountGroup.UUID(rule.getGroup().getUUID().get()));
        }
      }
    }

    if (iUser.getEffectiveGroups().containsAnyOf(okGroupIds)) {
      return Capable.OK;
    }

    if (iUser.getEffectiveGroups().containsAnyOf(missingInfoGroupIds)) {
      final StringBuilder msg = new StringBuilder();
      for (ContributorAgreement ca : contributorAgreements) {
        if (ca.isRequireContactInformation()) {
          msg.append(ca.getName());
          break;
        }
      }
      msg.append(" contributor agreement requires");
      msg.append(" current contact information.\n");
      if (canonicalWebUrl != null) {
        msg.append("\nPlease review your contact information");
        msg.append(":\n\n  ");
        msg.append(canonicalWebUrl);
        msg.append("#");
        msg.append(PageLinks.SETTINGS_CONTACT);
        msg.append("\n");
      }
      msg.append("\n");
      return new Capable(msg.toString());
    }

    final StringBuilder msg = new StringBuilder();
    msg.append(" A Contributor Agreement must be completed before uploading");
    if (canonicalWebUrl != null) {
      msg.append(":\n\n  ");
      msg.append(canonicalWebUrl);
      msg.append("#");
      msg.append(PageLinks.SETTINGS_AGREEMENTS);
      msg.append("\n");
    } else {
      msg.append(".");
    }
    msg.append("\n");
    return new Capable(msg.toString());
  }

  private static boolean missing(final String value) {
    return value == null || value.trim().equals("");
  }

  private boolean canPerformOnAnyRef(String permissionName) {
    for (SectionMatcher matcher : access()) {
      AccessSection section = matcher.section;
      Permission permission = section.getPermission(permissionName);
      if (permission == null) {
        continue;
      }

      for (PermissionRule rule : permission.getRules()) {
        if (rule.isBlock() || rule.isDeny() || !match(rule)) {
          continue;
        }

        // Being in a group that was granted this permission is only an
        // approximation.  There might be overrides and doNotInherit
        // that would render this to be false.
        //
        if (controlForRef(section.getName()).canPerform(permissionName)) {
          return true;
        } else {
          break;
        }
      }
    }

    return false;
  }

  private boolean canPerformOnAllRefs(String permission, Set<String> except) {
    boolean canPerform = false;
    Set<String> patterns = allRefPatterns(permission);
    if (patterns.contains(AccessSection.ALL)) {
      // Only possible if granted on the pattern that
      // matches every possible reference.  Check all
      // patterns also have the permission.
      //
      for (final String pattern : patterns) {
        if (controlForRef(pattern).canPerform(permission)) {
          canPerform = true;
        } else if (except.contains(pattern)) {
          continue;
        } else {
          return false;
        }
      }
    }
    return canPerform;
  }

  private Set<String> allRefPatterns(String permissionName) {
    Set<String> all = new HashSet<String>();
    for (SectionMatcher matcher : access()) {
      AccessSection section = matcher.section;
      Permission permission = section.getPermission(permissionName);
      if (permission != null) {
        all.add(section.getName());
      }
    }
    return all;
  }

  private List<SectionMatcher> access() {
    if (allSections == null) {
      allSections = state.getAllSections();
    }
    return allSections;
  }

  private List<SectionMatcher> localAccess() {
    if (localSections == null) {
      localSections = state.getLocalAccessSections();
    }
    return localSections;
  }

  boolean match(PermissionRule rule) {
    return match(rule.getGroup().getUUID());
  }

  boolean match(AccountGroup.UUID uuid) {
    if (AccountGroup.PROJECT_OWNERS.equals(uuid)) {
      return isDeclaredOwner();
    } else {
      return user.getEffectiveGroups().contains(uuid);
    }
  }

  public boolean canRunUploadPack() {
    for (AccountGroup.UUID group : uploadGroups) {
      if (match(group)) {
        return true;
      }
    }
    return false;
  }

  public boolean canRunReceivePack() {
    for (AccountGroup.UUID group : receiveGroups) {
      if (match(group)) {
        return true;
      }
    }
    return false;
  }

  public boolean canReadCommit(RevWalk rw, RevCommit commit) {
    Project.NameKey projName = state.getProject().getNameKey();
    try {
      Repository repo = repoManager.openRepository(projName);
      try {
        Map<String, Ref> allRefs = repo.getRefDatabase().getRefs(ALL);
        for (Entry<String, Ref> entry : allRefs.entrySet()) {
          String refName = entry.getKey();
          if (!refName.startsWith("refs/heads") && !refName.startsWith("refs/tags")) {
            continue;
          }
          RevCommit tip;
          try {
            tip = rw.parseCommit(entry.getValue().getObjectId());
          } catch (IncorrectObjectTypeException e) {
            continue;
          }
          if (rw.isMergedInto(commit, tip)
              && controlForRef(entry.getKey()).canPerform(Permission.READ)) {
            return true;
          }
        }
      } finally {
        repo.close();
      }
    } catch (IOException e) {
      String msg =
          String.format(
              "Cannot verify permissions to commit object %s in repository %s",
              commit.name(), projName.get());
      log.error(msg, e);
    }
    return controlForRef("refs/*").canPerform(Permission.READ);
  }
}
