// Copyright (C) 2014 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.plugins;

import static com.google.common.base.Preconditions.checkState;
import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.common.collect.ImmutableMap;
import com.google.gerrit.extensions.annotations.Export;
import com.google.gerrit.server.plugins.Plugin.ApiType;
import com.google.inject.Module;
import com.google.inject.servlet.ServletModule;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Modifier;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.jar.Manifest;

/**
 * Base plugin scanner for a set of pre-loaded classes.
 *
 * <p>Utility base class for simplifying the development of Server plugin scanner based on a set of
 * externally pre-loaded classes.
 *
 * <p>Extending this class you can implement very easily a PluginContentScanner from a set of
 * pre-loaded Java Classes and an API Type. The convention used by this class is: - there is at most
 * one Guice module per Gerrit module type (SysModule, HttpModule, SshModule) - plugin is set to be
 * restartable in Gerrit Plugin MANIFEST - only Export and Listen annotated classes can be
 * self-discovered
 */
public abstract class AbstractPreloadedPluginScanner implements PluginContentScanner {
  protected final String pluginName;
  protected final String pluginVersion;
  protected final Set<Class<?>> preloadedClasses;
  protected final ApiType apiType;

  private Class<?> sshModuleClass;
  private Class<?> httpModuleClass;
  private Class<?> sysModuleClass;

  public AbstractPreloadedPluginScanner(
      String pluginName,
      String pluginVersion,
      Set<Class<?>> preloadedClasses,
      Plugin.ApiType apiType) {
    this.pluginName = pluginName;
    this.pluginVersion = pluginVersion;
    this.preloadedClasses = preloadedClasses;
    this.apiType = apiType;
  }

  @Override
  public Manifest getManifest() throws IOException {
    scanGuiceModules(preloadedClasses);
    StringBuilder manifestString =
        new StringBuilder(
            "PluginName: "
                + pluginName
                + "\n"
                + "Implementation-Version: "
                + pluginVersion
                + "\n"
                + "Gerrit-ReloadMode: restart\n"
                + "Gerrit-ApiType: "
                + apiType
                + "\n");
    appendIfNotNull(manifestString, "Gerrit-SshModule: ", sshModuleClass);
    appendIfNotNull(manifestString, "Gerrit-HttpModule: ", httpModuleClass);
    appendIfNotNull(manifestString, "Gerrit-Module: ", sysModuleClass);
    return new Manifest(new ByteArrayInputStream(manifestString.toString().getBytes(UTF_8)));
  }

  @Override
  public Map<Class<? extends Annotation>, Iterable<ExtensionMetaData>> scan(
      String pluginName, Iterable<Class<? extends Annotation>> annotations)
      throws InvalidPluginException {
    ImmutableMap.Builder<Class<? extends Annotation>, Iterable<ExtensionMetaData>> result =
        ImmutableMap.builder();

    for (Class<? extends Annotation> annotation : annotations) {
      Set<ExtensionMetaData> classMetaDataSet = new HashSet<>();
      result.put(annotation, classMetaDataSet);

      for (Class<?> clazz : preloadedClasses) {
        if (!Modifier.isAbstract(clazz.getModifiers()) && clazz.getAnnotation(annotation) != null) {
          classMetaDataSet.add(
              new ExtensionMetaData(clazz.getName(), getExportAnnotationValue(clazz, annotation)));
        }
      }
    }
    return result.build();
  }

  private void appendIfNotNull(StringBuilder string, String header, Class<?> guiceModuleClass) {
    if (guiceModuleClass != null) {
      string.append(header);
      string.append(guiceModuleClass.getName());
      string.append("\n");
    }
  }

  private void scanGuiceModules(Set<Class<?>> classes) throws IOException {
    try {
      Class<?> sysModuleBaseClass = Module.class;
      Class<?> httpModuleBaseClass = ServletModule.class;
      Class<?> sshModuleBaseClass = Class.forName("com.google.gerrit.sshd.CommandModule");
      sshModuleClass = null;
      httpModuleClass = null;
      sysModuleClass = null;

      for (Class<?> clazz : classes) {
        if (clazz.isLocalClass()) {
          continue;
        }

        if (sshModuleBaseClass.isAssignableFrom(clazz)) {
          sshModuleClass = getUniqueGuiceModule(sshModuleBaseClass, sshModuleClass, clazz);
        } else if (httpModuleBaseClass.isAssignableFrom(clazz)) {
          httpModuleClass = getUniqueGuiceModule(httpModuleBaseClass, httpModuleClass, clazz);
        } else if (sysModuleBaseClass.isAssignableFrom(clazz)) {
          sysModuleClass = getUniqueGuiceModule(sysModuleBaseClass, sysModuleClass, clazz);
        }
      }
    } catch (ClassNotFoundException e) {
      throw new IOException("Cannot find base Gerrit classes for Guice Plugin Modules", e);
    }
  }

  private Class<?> getUniqueGuiceModule(
      Class<?> guiceModuleBaseClass,
      Class<?> existingGuiceModuleName,
      Class<?> newGuiceModuleClass) {
    checkState(
        existingGuiceModuleName == null,
        "Multiple %s implementations: %s, %s",
        guiceModuleBaseClass,
        existingGuiceModuleName,
        newGuiceModuleClass);
    return newGuiceModuleClass;
  }

  private String getExportAnnotationValue(
      Class<?> scriptClass, Class<? extends Annotation> annotation) {
    return annotation == Export.class ? scriptClass.getAnnotation(Export.class).value() : "";
  }
}
