// Copyright (C) 2013 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.account;

import com.google.gerrit.extensions.annotations.CapabilityScope;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.CapabilityControl;
import com.google.inject.Provider;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.annotation.Annotation;

public class CapabilityUtils {
  private static final Logger log = LoggerFactory
      .getLogger(CapabilityUtils.class);

  public static void checkRequiresCapability(Provider<CurrentUser> userProvider,
      String pluginName, Class<?> clazz)
      throws AuthException {
    RequiresCapability rc = getClassAnnotation(clazz, RequiresCapability.class);
    if (rc != null) {
      CurrentUser user = userProvider.get();
      CapabilityControl ctl = user.getCapabilities();
      if (ctl.canAdministrateServer()) {
        return;
      }

      String capability = rc.value();
      if (pluginName != null && !"gerrit".equals(pluginName)
         && (rc.scope() == CapabilityScope.PLUGIN
          || rc.scope() == CapabilityScope.CONTEXT)) {
        capability = String.format("%s-%s", pluginName, rc.value());
      } else if (rc.scope() == CapabilityScope.PLUGIN) {
        log.error(String.format(
            "Class %s uses @%s(scope=%s), but is not within a plugin",
            clazz.getName(),
            RequiresCapability.class.getSimpleName(),
            CapabilityScope.PLUGIN.name()));
        throw new AuthException("cannot check capability");
      }

      if (!ctl.canPerform(capability)) {
        throw new AuthException(String.format(
            "Capability %s is required to access this resource",
            capability));
      }
    }
  }

  /**
   * Find an instance of the specified annotation, walking up the inheritance
   * tree if necessary.
   *
   * @param <T> Annotation type to search for
   * @param clazz root class to search, may be null
   * @param annotationClass class object of Annotation subclass to search for
   * @return the requested annotation or null if none
   */
  private static <T extends Annotation> T getClassAnnotation(Class<?> clazz,
      Class<T> annotationClass) {
    for (; clazz != null; clazz = clazz.getSuperclass()) {
      T t = clazz.getAnnotation(annotationClass);
      if (t != null) {
        return t;
      }
    }
    return null;
  }
}
