// 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.server.project;

import com.google.gerrit.reviewdb.AccountGroup;
import com.google.gerrit.reviewdb.ApprovalCategory;
import com.google.gerrit.reviewdb.Project;
import com.google.gerrit.reviewdb.RefRight;
import com.google.gerrit.server.AnonymousUser;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.config.WildProjectName;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

/** Cached information on a project. */
public class ProjectState {
  public interface Factory {
    ProjectState create(Project project, Collection<RefRight> localRights);
  }

  private final AnonymousUser anonymousUser;
  private final Project.NameKey wildProject;
  private final ProjectCache projectCache;
  private final ProjectControl.AssistedFactory projectControlFactory;

  private final Project project;
  private final Collection<RefRight> localRights;
  private final Set<AccountGroup.Id> localOwners;

  private volatile Collection<RefRight> inheritedRights;

  @Inject
  protected ProjectState(final AnonymousUser anonymousUser,
      final ProjectCache projectCache,
      @WildProjectName final Project.NameKey wildProject,
      final ProjectControl.AssistedFactory projectControlFactory,
      @Assisted final Project project,
      @Assisted Collection<RefRight> rights) {
    this.anonymousUser = anonymousUser;
    this.projectCache = projectCache;
    this.wildProject = wildProject;
    this.projectControlFactory = projectControlFactory;

    if (wildProject.equals(project.getNameKey())) {
      rights = new ArrayList<RefRight>(rights);
      for (Iterator<RefRight> itr = rights.iterator(); itr.hasNext();) {
        if (!itr.next().getApprovalCategoryId().canBeOnWildProject()) {
          itr.remove();
        }
      }
      rights = Collections.unmodifiableCollection(rights);
    }

    this.project = project;
    this.localRights = rights;

    final HashSet<AccountGroup.Id> groups = new HashSet<AccountGroup.Id>();
    for (final RefRight right : rights) {
      if (ApprovalCategory.OWN.equals(right.getApprovalCategoryId())
          && right.getMaxValue() > 0
          && right.getRefPattern().equals(RefRight.ALL)) {
        groups.add(right.getAccountGroupId());
      }
    }
    localOwners = Collections.unmodifiableSet(groups);
  }

  public Project getProject() {
    return project;
  }

  /** Get the rights that pertain only to this project. */
  public Collection<RefRight> getLocalRights() {
    return localRights;
  }

  /**
   * Get the rights that pertain only to this project.
   *
   * @param action the category requested.
   * @return immutable collection of rights for the requested category.
   */
  public Collection<RefRight> getLocalRights(ApprovalCategory.Id action) {
    return filter(getLocalRights(), action);
  }

  /** Get the rights this project inherits from the wild project. */
  public Collection<RefRight> getInheritedRights() {
    if (inheritedRights == null) {
      inheritedRights = computeInheritedRights();
    }
    return inheritedRights;
  }

  void setInheritedRights(Collection<RefRight> all) {
    inheritedRights = all;
  }

  private Collection<RefRight> computeInheritedRights() {
    if (isSpecialWildProject()) {
      return Collections.emptyList();
    }

    List<RefRight> inherited = new ArrayList<RefRight>();
    Set<Project.NameKey> seen = new HashSet<Project.NameKey>();
    Project.NameKey parent = project.getParent();

    while (parent != null && seen.add(parent)) {
      ProjectState s = projectCache.get(parent);
      if (s != null) {
        inherited.addAll(s.getLocalRights());
        parent = s.getProject().getParent();
      } else {
        break;
      }
    }

    // Wild project is the parent, or the root of the tree
    if (parent == null) {
      inherited.addAll(getWildProjectRights());
    }

    return Collections.unmodifiableCollection(inherited);
  }

  private Collection<RefRight> getWildProjectRights() {
    final ProjectState s = projectCache.get(wildProject);
    return s != null ? s.getLocalRights() : Collections.<RefRight> emptyList();
  }

  /**
   * Utility class that is needed to filter overridden refrights
   */
  private static class Grant {
    final AccountGroup.Id group;
    final String pattern;

    private Grant(AccountGroup.Id group, String pattern) {
      this.group = group;
      this.pattern = pattern;
    }

    @Override
    public boolean equals(Object o) {
      if (o == null)
        return false;
      Grant grant = (Grant) o;
      return group.equals(grant.group) && pattern.equals(grant.pattern);
    }

    @Override
    public int hashCode() {
      int result = group.hashCode();
      result = 31 * result + pattern.hashCode();
      return result;
    }
  }

  /**
   * Get the rights this project has and inherits from the wild project.
   *
   * @param action the category requested.
   * @param dropOverridden whether to remove inherited permissions in case if we have a
   *     local one that matches (action,group,ref)
   * @return immutable collection of rights for the requested category.
   */
  public Collection<RefRight> getAllRights(ApprovalCategory.Id action, boolean dropOverridden) {
    Collection<RefRight> rights = new LinkedList<RefRight>(getLocalRights(action));
    rights.addAll(filter(getInheritedRights(), action));
    if (dropOverridden) {
      Set<Grant> grants = new HashSet<Grant>();
      Iterator<RefRight> iter = rights.iterator();
      while (iter.hasNext()) {
        RefRight right = iter.next();

        Grant grant = new Grant(right.getAccountGroupId(), right.getRefPattern());
        if (grants.contains(grant)) {
          iter.remove();
        } else {
          grants.add(grant);
        }
      }
    }
    return Collections.unmodifiableCollection(rights);
  }

  /** Is this the special wild project which manages inherited rights? */
  public boolean isSpecialWildProject() {
    return project.getNameKey().equals(wildProject);
  }

  /**
   * @return all {@link AccountGroup}'s to which the owner privilege for
   *         'refs/*' is assigned for this project (the local owners), if there
   *         are no local owners the local owners of the nearest parent project
   *         that has local owners are returned
   */
  public Set<AccountGroup.Id> getOwners() {
    if (!localOwners.isEmpty() || isSpecialWildProject()
        || project.getParent() == null) {
      return localOwners;
    }

    final ProjectState parent = projectCache.get(project.getParent());
    if (parent != null) {
      return parent.getOwners();
    }

    return Collections.emptySet();
  }

  /**
   * @return all {@link AccountGroup}'s that are allowed to administrate the
   *         complete project. This includes all groups to which the owner
   *         privilege for 'refs/*' is assigned for this project (the local
   *         owners) and all groups to which the owner privilege for 'refs/*' is
   *         assigned for one of the parent projects (the inherited owners).
   */
  public Set<AccountGroup.Id> getAllOwners() {
    final HashSet<AccountGroup.Id> owners = new HashSet<AccountGroup.Id>();
    for (final RefRight right : getAllRights(ApprovalCategory.OWN, true)) {
      if (right.getMaxValue() > 0 && right.getRefPattern().equals(RefRight.ALL)) {
        owners.add(right.getAccountGroupId());
      }
    }
    return Collections.unmodifiableSet(owners);
  }

  public ProjectControl controlForAnonymousUser() {
    return controlFor(anonymousUser);
  }

  public ProjectControl controlFor(final CurrentUser user) {
    return projectControlFactory.create(user, this);
  }

  private static Collection<RefRight> filter(Collection<RefRight> all,
      ApprovalCategory.Id actionId) {
    if (all.isEmpty()) {
      return Collections.emptyList();
    }
    final Collection<RefRight> mine = new ArrayList<RefRight>(all.size());
    for (final RefRight right : all) {
      if (right.getApprovalCategoryId().equals(actionId)) {
        mine.add(right);
      }
    }
    if (mine.isEmpty()) {
      return Collections.emptyList();
    }
    return Collections.unmodifiableCollection(mine);
  }
}
