// Copyright (C) 2011 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 com.google.gerrit.server.project.RefControl.isRE;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.gerrit.common.data.AccessSection;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.common.data.PermissionRule;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Project;
import com.google.inject.Inject;
import com.google.inject.Singleton;

import java.util.ArrayList;
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;

/**
 * Effective permissions applied to a reference in a project.
 * <p>
 * A collection may be user specific if a matching {@link AccessSection} uses
 * "${username}" in its name. The permissions granted in that section may only
 * be granted to the username that appears in the reference name, and also only
 * if the user is a member of the relevant group.
 */
public class PermissionCollection {
  @Singleton
  public static class Factory {
    private final SectionSortCache sorter;

    @Inject
    Factory(SectionSortCache sorter) {
      this.sorter = sorter;
    }

    /**
     * Get all permissions that apply to a reference.
     *
     * @param matcherList collection of sections that should be considered, in
     *        priority order (project specific definitions must appear before
     *        inherited ones).
     * @param ref reference being accessed.
     * @param usernames if the reference is a per-user reference, access sections
     *        using the parameter variable "${username}" will first have each of
     *        {@code usernames} inserted into them before seeing if they apply to
     *        the reference named by {@code ref}. If null or empty, per-user
     *        references are ignored.
     * @return map of permissions that apply to this reference, keyed by
     *         permission name.
     */
    PermissionCollection filter(Iterable<SectionMatcher> matcherList,
        String ref, Collection<String> usernames) {
      if (isRE(ref)) {
        ref = RefControl.shortestExample(ref);
      } else if (ref.endsWith("/*")) {
        ref = ref.substring(0, ref.length() - 1);
      }

      boolean hasUsernames = usernames != null && !usernames.isEmpty();
      boolean perUser = false;
      Map<AccessSection, Project.NameKey> sectionToProject = Maps.newLinkedHashMap();
      for (SectionMatcher sm : matcherList) {
        // If the matcher has to expand parameters and its prefix matches the
        // reference there is a very good chance the reference is actually user
        // specific, even if the matcher does not match the reference. Since its
        // difficult to prove this is true all of the time, use an approximation
        // to prevent reuse of collections across users accessing the same
        // reference at the same time.
        //
        // This check usually gets caching right, as most per-user references
        // use a common prefix like "refs/sandbox/" or "refs/heads/users/"
        // that will never be shared with non-user references, and the per-user
        // references are usually less frequent than the non-user references.
        //
        if (hasUsernames) {
          if (!perUser && sm.matcher instanceof RefPatternMatcher.ExpandParameters) {
            perUser = ((RefPatternMatcher.ExpandParameters) sm.matcher).matchPrefix(ref);
          }
          for (String username : usernames) {
            if (sm.match(ref, username)) {
              sectionToProject.put(sm.section, sm.project);
              break;
            }
          }
        } else if (sm.match(ref, null)) {
          sectionToProject.put(sm.section, sm.project);
        }
      }
      List<AccessSection> sections = Lists.newArrayList(sectionToProject.keySet());
      sorter.sort(ref, sections);

      Set<SeenRule> seen = new HashSet<SeenRule>();
      Set<String> exclusiveGroupPermissions = new HashSet<String>();

      HashMap<String, List<PermissionRule>> permissions =
          new HashMap<String, List<PermissionRule>>();
      Map<PermissionRule, ProjectRef> ruleProps = Maps.newIdentityHashMap();
      for (AccessSection section : sections) {
        Project.NameKey project = sectionToProject.get(section);
        for (Permission permission : section.getPermissions()) {
          boolean exclusivePermissionExists =
              exclusiveGroupPermissions.contains(permission.getName());

          for (PermissionRule rule : permission.getRules()) {
            SeenRule s = new SeenRule(section, permission, rule);
            boolean addRule;
            if (rule.isBlock()) {
              addRule = true;
            } else {
              addRule = seen.add(s) && !rule.isDeny() && !exclusivePermissionExists;
            }
            if (addRule) {
              List<PermissionRule> r = permissions.get(permission.getName());
              if (r == null) {
                r = new ArrayList<PermissionRule>(2);
                permissions.put(permission.getName(), r);
              }
              r.add(rule);
              ruleProps.put(rule, new ProjectRef(project, section.getName()));
            }
          }

          if (permission.getExclusiveGroup()) {
            exclusiveGroupPermissions.add(permission.getName());
          }
        }
      }

      return new PermissionCollection(permissions, ruleProps, perUser);
    }
  }

  private final Map<String, List<PermissionRule>> rules;
  private final Map<PermissionRule, ProjectRef> ruleProps;
  private final boolean perUser;

  private PermissionCollection(Map<String, List<PermissionRule>> rules,
      Map<PermissionRule, ProjectRef> ruleProps,
      boolean perUser) {
    this.rules = rules;
    this.ruleProps = ruleProps;
    this.perUser = perUser;
  }

  /**
   * @return true if a "${username}" pattern might need to be expanded to build
   *         this collection, making the results user specific.
   */
  public boolean isUserSpecific() {
    return perUser;
  }

  /**
   * Obtain all permission rules for a given type of permission.
   *
   * @param permissionName type of permission.
   * @return all rules that apply to this reference, for any group. Never null;
   *         the empty list is returned when there are no rules for the requested
   *         permission name.
   */
  public List<PermissionRule> getPermission(String permissionName) {
    List<PermissionRule> r = rules.get(permissionName);
    return r != null ? r : Collections.<PermissionRule> emptyList();
  }

  ProjectRef getRuleProps(PermissionRule rule) {
    return ruleProps.get(rule);
  }

  /**
   * Obtain all declared permission rules that match the reference.
   *
   * @return all rules. The collection will iterate a permission if it was
   *         declared in the project configuration, either directly or
   *         inherited. If the project owner did not use a known permission (for
   *         example {@link Permission#FORGE_SERVER}, then it will not be
   *         represented in the result even if {@link #getPermission(String)}
   *         returns an empty list for the same permission.
   */
  public Iterable<Map.Entry<String, List<PermissionRule>>> getDeclaredPermissions() {
    return rules.entrySet();
  }

  /** Tracks whether or not a permission has been overridden. */
  private static class SeenRule {
    final String refPattern;
    final String permissionName;
    final AccountGroup.UUID group;

    SeenRule(AccessSection section, Permission permission, PermissionRule rule) {
      refPattern = section.getName();
      permissionName = permission.getName();
      group = rule.getGroup().getUUID();
    }

    @Override
    public int hashCode() {
      int hc = refPattern.hashCode();
      hc = hc * 31 + permissionName.hashCode();
      if (group != null) {
        hc = hc * 31 + group.hashCode();
      }
      return hc;
    }

    @Override
    public boolean equals(Object other) {
      if (other instanceof SeenRule) {
        SeenRule a = this;
        SeenRule b = (SeenRule) other;
        return a.refPattern.equals(b.refPattern) //
            && a.permissionName.equals(b.permissionName) //
            && eq(a.group, b.group);
      }
      return false;
    }

    private boolean eq(AccountGroup.UUID a, AccountGroup.UUID b) {
      return a != null && b != null && a.equals(b);
    }
  }
}
