/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.drill.exec.store;

import static com.google.common.base.Preconditions.checkNotNull;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.drill.common.config.DrillConfig;
import org.apache.drill.common.exceptions.ExecutionSetupException;
import org.apache.drill.common.logical.StoragePluginConfig;
import org.apache.drill.exec.ExecConstants;
import org.apache.drill.exec.planner.logical.StoragePlugins;
import org.apache.drill.exec.server.DrillbitContext;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Joiner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Plugin locator for the "classic" class-path method of locating connectors.
 * Connectors appear somewhere on the class path, and are subclasses of
 * {@link StoragePlugin}. The connector and its configuration class must
 * reside in Drill's default class loader.
 * <p>
 * Handles "classic" storage plugin classes which ship with Drill, or are
 * added to Drill's class path.
 * <p>
 * The plugin registry supports access from multiple threads concurrently.
 * This locator is therefore immutable after the {@code init()} call.
 * The set of plugin instances and configurations (managed by the registry)
 * changes during a run, but the set of known plugin classes is fixed.
 * <p>
 * We sometimes need to add special plugins for testing. Since we cannot
 * add them on the fly, we must add them at (test) startup time via
 * config properties.
 *
 * <h4>Plugin Implementations</h4>
 *
 * This class manages plugin implementation classes (AKA "connectors")
 * which must derive from {@code StoragePlugin}. Each must be configured
 * via a class derived from {@code StoragePluginConfig}. No two connectors
 * can share a configuration class. Each connector must have exactly one
 * associated configuration. (Actually, a single connector might handle
 * multiple configurations, but that seems an obscure use case.)
 * <p>
 * The constructor of the connector associates the two classes, and must
 * be of the form:<pre><code>
 * public SomePlugin(SomePluginConfig config,
 *                   DrillbitContext context,
 *                   String pluginName) {</code></pre>
 * <p>
 * Classes must be on the class path. Drill often caches the class path:
 * creating it at build time, then storing it in a file, to be read at
 * run time. If you are developing a plugin in an IDE, and this class
 * refuses to find the plugin, you can temporarly force a runtime
 * class path scan via setting the
 * {@code ClassPathScanner.IMPLEMENTATIONS_SCAN_CACHE} config property
 * to {@code false}. The various test "fixtures" provide an easy way
 * to set config properties per-test.
 * <p>
 * This locator ignores four categories of {@code StoragePluginConfig}
 * classes:
 * <ul>
 * <li>Interfaces or abstract classes</li>
 * <li>Those that do not have the constructor described above.</li>
 * <li>System plugins with the {@code SystemPlugin} annotation.</li>
 * <li>Private test plugins with the {@code PrivatePlugin}
 * annotation.</li>
 * </ul>
 *
 * <h4>Config Properties</h4>
 *
 * <dl>
 * <dt>{@code ExecConstants.PRIVATE_CONNECTORS}
 * ({@code drill.exec.storage.private_connectors})</dt>
 * <dd>An optional list of private plugin class names. Private plugins
 * are valid instances of {@code StoragePlugin} which have the
 * {@code PrivatePlugin} annotation and so are not automatically
 * loaded.</dd>
 * </dl>
 */
public class ClassicConnectorLocator implements ConnectorLocator {
  private static final Logger logger = LoggerFactory.getLogger(ClassicConnectorLocator.class);

  private final PluginRegistryContext context;
  // Here "plugin" means storage plugin class
  private final Map<Class<? extends StoragePluginConfig>,
                    Constructor<? extends StoragePlugin>> availablePlugins = new IdentityHashMap<>();
  private PluginBootstrapLoader bootstrapLoader;

  public ClassicConnectorLocator(PluginRegistryContext context) {
    this.context = checkNotNull(context);
    this.bootstrapLoader = new PluginBootstrapLoaderImpl(context);
  }

  // TODO: Provide a list of plugin classes to avoid doing
  // the scan twice.
  @Override
  public void init() {

    // Build the list of all available storage plugin class constructors.
    final Collection<Class<? extends StoragePlugin>> pluginClasses =
        context.classpathScan().getImplementations(StoragePlugin.class);
    final String lineBrokenList =
        pluginClasses.size() == 0
            ? "" : "\n\t- " + Joiner.on("\n\t- ").join(pluginClasses);
    logger.debug("Found {} storage plugin configuration classes: {}.",
        pluginClasses.size(), lineBrokenList);
    for (Class<? extends StoragePlugin> plugin : pluginClasses) {

      // Skip system and private plugins
      if (!plugin.isAnnotationPresent(SystemPlugin.class) &&
          !plugin.isAnnotationPresent(PrivatePlugin.class)) {
        registerPlugin(plugin);
      }
    }

    // Any private connectors to load?
    // Expected to be in the same class loader as this class.
    DrillConfig config = context.config();
    if (config.hasPath(ExecConstants.PRIVATE_CONNECTORS)) {
      List<String> privateConfigs = config.getStringList(ExecConstants.PRIVATE_CONNECTORS);
      for (String privateName : privateConfigs) {
        registerPrivatePlugin(privateName);
      }
    }
  }

  @SuppressWarnings("unchecked")
  private void registerPrivatePlugin(String pluginName) {
    Class<?> pluginClass;
    try {
      ClassLoader cl = getClass().getClassLoader();
      pluginClass = cl.loadClass(pluginName);
    } catch (ClassNotFoundException e) {
      throw new IllegalArgumentException("Private plugin class not found: " + pluginName, e);
    }
    if (!StoragePlugin.class.isAssignableFrom(pluginClass)) {
      throw new IllegalArgumentException("Private plugin class does not extend StoragePlugin: " + pluginName);
    }
    if (!registerPlugin((Class<? extends StoragePlugin>) pluginClass)) {
      throw new IllegalArgumentException("Private plugin class not valid, see logs: " + pluginName);
    }
  }

  private boolean registerPlugin(Class<? extends StoragePlugin> plugin) {
    Map<Class<? extends StoragePluginConfig>, Constructor<? extends StoragePlugin>> ctors = constuctorsFor(plugin);
    if (ctors.isEmpty()) {
      logger.debug("Skipping registration of StoragePlugin {} as it doesn't have a constructor with the parameters "
          + "of (StoragePluginConfig, Config)", plugin.getCanonicalName());
      return false;
    } else {
      for (Entry<Class<? extends StoragePluginConfig>, Constructor<? extends StoragePlugin>> ctor : ctors.entrySet()) {
        if (availablePlugins.containsKey(ctor.getKey())) {
          logger.warn(String.format("Two storage plugins cannot use the same config class. " +
              "Found conflict %s and %s both use %s. Only the first added to registry.",
              availablePlugins.get(ctor.getKey()).getDeclaringClass().getName(),
              ctor.getValue().getDeclaringClass().getName(),
              ctor.getKey().getName()));
        } else {
          availablePlugins.put(ctor.getKey(), ctor.getValue());
        }
      }
      return true;
    }
  }

  @SuppressWarnings("unchecked")
  public static Map<Class<? extends StoragePluginConfig>, Constructor<? extends StoragePlugin>>
      constuctorsFor(Class<? extends StoragePlugin> plugin) {
    Map<Class<? extends StoragePluginConfig>, Constructor<? extends StoragePlugin>> ctors = new IdentityHashMap<>();
    for (Constructor<?> c : plugin.getConstructors()) {
      Class<?>[] params = c.getParameterTypes();
      if (params.length != 3
          || !StoragePluginConfig.class.isAssignableFrom(params[0])
          || params[1] != DrillbitContext.class
          || params[2] != String.class) {
        logger.debug("Skipping StoragePlugin constructor {} for plugin class {} since it doesn't implement a "
            + "constructor(StoragePluginConfig, DrillbitContext, String)", c, plugin);
        continue;
      }
      Class<? extends StoragePluginConfig> configClass = (Class<? extends StoragePluginConfig>) params[0];
      ctors.put(configClass, (Constructor<? extends StoragePlugin>) c);
    }
    return ctors;
  }

  @Override
  @VisibleForTesting
  public Set<Class<? extends StoragePluginConfig>> configClasses() {
    return availablePlugins.keySet();
  }

  /**
   * Classic storage plugins do not provide default configurations.
   */
  @Override
  public StoragePlugin get(String name) {
    return null;
  }

  @Override
  public List<StoragePlugin> intrinsicPlugins() {
    return null;
  }

  /**
   * Read bootstrap storage plugins
   * {@link ExecConstants#BOOTSTRAP_STORAGE_PLUGINS_FILE} and format plugins
   * {@link ExecConstants#BOOTSTRAP_FORMAT_PLUGINS_FILE} files for the first
   * fresh install of Drill.
   *
   * @return bootstrap storage plugins
   * @throws IOException if a read error occurs
   */
  @Override
  public StoragePlugins bootstrapPlugins() throws IOException {
    return bootstrapLoader.bootstrapPlugins();
  }

  @Override
  public StoragePlugins updatedPlugins() {
    return bootstrapLoader.updatedPlugins();
  }

  @Override
  public void onUpgrade() {
    bootstrapLoader.onUpgrade();
    bootstrapLoader = null;
  }

  /**
   * Creates plugin instance with the given {@code name} and configuration {@code pluginConfig}.
   * The plugin need to be present in a list of available plugins and be enabled in the configuration
   *
   * @param name name of the plugin
   * @param pluginConfig plugin configuration
   * @return plugin client or {@code null} if plugin is disabled
   */
  @Override
  public StoragePlugin create(String name, StoragePluginConfig pluginConfig) throws ExecutionSetupException {
    StoragePlugin plugin;
    Constructor<? extends StoragePlugin> constructor = availablePlugins.get(pluginConfig.getClass());
    if (constructor == null) {
      throw new ExecutionSetupException(String.format("Failure finding StoragePlugin constructor for config %s",
          pluginConfig.getClass().getName()));
    }
    try {
      plugin = constructor.newInstance(pluginConfig, context.drillbitContext(), name);
      return plugin;
    } catch (ReflectiveOperationException e) {
      Throwable t = e instanceof InvocationTargetException ? ((InvocationTargetException) e).getTargetException() : e;
      if (t instanceof ExecutionSetupException) {
        throw ((ExecutionSetupException) t);
      }
      throw new ExecutionSetupException(String.format(
          "Failure setting up new storage plugin configuration for config %s",
          pluginConfig.getClass().getSimpleName()), t);
    }
  }

  @Override
  public boolean storable() {
    return true;
  }

  @Override
  public Class<? extends StoragePlugin> connectorClassFor(
      Class<? extends StoragePluginConfig> configClass) {
    Constructor<? extends StoragePlugin> constructor =
        availablePlugins.get(configClass);
    return constructor == null ? null : constructor.getDeclaringClass();
  }

  @Override
  public void close() { }
}
