// Copyright (C) 2017 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.permissions;

import com.google.common.collect.ImmutableMap;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.extensions.annotations.CapabilityScope;
import com.google.gerrit.extensions.annotations.RequiresAnyCapability;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.extensions.api.access.GlobalOrPluginPermission;
import com.google.gerrit.extensions.api.access.PluginPermission;
import java.lang.annotation.Annotation;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Locale;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** Global server permissions built into Gerrit. */
public enum GlobalPermission implements GlobalOrPluginPermission {
  ACCESS_DATABASE(GlobalCapability.ACCESS_DATABASE),
  ADMINISTRATE_SERVER(GlobalCapability.ADMINISTRATE_SERVER),
  CREATE_ACCOUNT(GlobalCapability.CREATE_ACCOUNT),
  CREATE_GROUP(GlobalCapability.CREATE_GROUP),
  CREATE_PROJECT(GlobalCapability.CREATE_PROJECT),
  EMAIL_REVIEWERS(GlobalCapability.EMAIL_REVIEWERS),
  FLUSH_CACHES(GlobalCapability.FLUSH_CACHES),
  KILL_TASK(GlobalCapability.KILL_TASK),
  MAINTAIN_SERVER(GlobalCapability.MAINTAIN_SERVER),
  MODIFY_ACCOUNT(GlobalCapability.MODIFY_ACCOUNT),
  RUN_AS(GlobalCapability.RUN_AS),
  RUN_GC(GlobalCapability.RUN_GC),
  STREAM_EVENTS(GlobalCapability.STREAM_EVENTS),
  VIEW_ALL_ACCOUNTS(GlobalCapability.VIEW_ALL_ACCOUNTS),
  VIEW_CACHES(GlobalCapability.VIEW_CACHES),
  VIEW_CONNECTIONS(GlobalCapability.VIEW_CONNECTIONS),
  VIEW_PLUGINS(GlobalCapability.VIEW_PLUGINS),
  VIEW_QUEUE(GlobalCapability.VIEW_QUEUE);

  private static final Logger log = LoggerFactory.getLogger(GlobalPermission.class);
  private static final ImmutableMap<String, GlobalPermission> BY_NAME;

  static {
    ImmutableMap.Builder<String, GlobalPermission> m = ImmutableMap.builder();
    for (GlobalPermission p : values()) {
      m.put(p.permissionName(), p);
    }
    BY_NAME = m.build();
  }

  @Nullable
  public static GlobalPermission byName(String name) {
    return BY_NAME.get(name);
  }

  /**
   * Extracts the {@code @RequiresCapability} or {@code @RequiresAnyCapability} annotation.
   *
   * @param pluginName name of the declaring plugin. May be {@code null} or {@code "gerrit"} for
   *     classes originating from the core server.
   * @param clazz target class to extract annotation from.
   * @return empty set if no annotations were found, or a collection of permissions, any of which
   *     are suitable to enable access.
   * @throws PermissionBackendException the annotation could not be parsed.
   */
  public static Set<GlobalOrPluginPermission> fromAnnotation(
      @Nullable String pluginName, Class<?> clazz) throws PermissionBackendException {
    RequiresCapability rc = findAnnotation(clazz, RequiresCapability.class);
    RequiresAnyCapability rac = findAnnotation(clazz, RequiresAnyCapability.class);
    if (rc != null && rac != null) {
      log.error(
          "Class {} uses both @{} and @{}",
          clazz.getName(),
          RequiresCapability.class.getSimpleName(),
          RequiresAnyCapability.class.getSimpleName());
      throw new PermissionBackendException("cannot extract permission");
    } else if (rc != null) {
      return Collections.singleton(
          resolve(
              pluginName,
              rc.value(),
              rc.scope(),
              rc.fallBackToAdmin(),
              clazz,
              RequiresCapability.class));
    } else if (rac != null) {
      Set<GlobalOrPluginPermission> r = new LinkedHashSet<>();
      for (String capability : rac.value()) {
        r.add(
            resolve(
                pluginName,
                capability,
                rac.scope(),
                rac.fallBackToAdmin(),
                clazz,
                RequiresAnyCapability.class));
      }
      return Collections.unmodifiableSet(r);
    } else {
      return Collections.emptySet();
    }
  }

  public static Set<GlobalOrPluginPermission> fromAnnotation(Class<?> clazz)
      throws PermissionBackendException {
    return fromAnnotation(null, clazz);
  }

  private final String name;

  GlobalPermission(String name) {
    this.name = name;
  }

  /** @return name used in {@code project.config} permissions. */
  @Override
  public String permissionName() {
    return name;
  }

  @Override
  public String describeForException() {
    return toString().toLowerCase(Locale.US).replace('_', ' ');
  }

  private static GlobalOrPluginPermission resolve(
      @Nullable String pluginName,
      String capability,
      CapabilityScope scope,
      boolean fallBackToAdmin,
      Class<?> clazz,
      Class<?> annotationClass)
      throws PermissionBackendException {
    if (pluginName != null
        && !"gerrit".equals(pluginName)
        && (scope == CapabilityScope.PLUGIN || scope == CapabilityScope.CONTEXT)) {
      return new PluginPermission(pluginName, capability, fallBackToAdmin);
    }

    if (scope == CapabilityScope.PLUGIN) {
      log.error(
          "Class {} uses @{}(scope={}), but is not within a plugin",
          clazz.getName(),
          annotationClass.getSimpleName(),
          scope.name());
      throw new PermissionBackendException("cannot extract permission");
    }

    GlobalPermission perm = byName(capability);
    if (perm == null) {
      log.error("Class {} requires unknown capability {}", clazz.getName(), capability);
      throw new PermissionBackendException("cannot extract permission");
    }
    return perm;
  }

  @Nullable
  private static <T extends Annotation> T findAnnotation(Class<?> clazz, Class<T> annotation) {
    for (; clazz != null; clazz = clazz.getSuperclass()) {
      T t = clazz.getAnnotation(annotation);
      if (t != null) {
        return t;
      }
    }
    return null;
  }
}
