/*
 * 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 com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.drill.shaded.guava.com.google.common.base.Charsets;
import org.apache.drill.shaded.guava.com.google.common.io.Resources;
import com.jasonclawson.jackson.dataformat.hocon.HoconFactory;
import org.apache.drill.common.config.ConfigConstants;
import org.apache.drill.common.config.LogicalPlanPersistence;
import org.apache.drill.common.exceptions.DrillRuntimeException;
import org.apache.drill.common.logical.StoragePluginConfig;
import org.apache.drill.common.scanner.ClassPathScanner;
import org.apache.drill.exec.planner.logical.StoragePlugins;
import org.apache.drill.exec.server.DrillbitContext;
import org.apache.drill.exec.store.sys.PersistentStore;
import org.apache.drill.exec.util.ActionOnFile;

import javax.annotation.Nullable;
import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.net.URL;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

import static org.apache.drill.exec.store.StoragePluginRegistry.ACTION_ON_STORAGE_PLUGINS_OVERRIDE_FILE;

/**
 * Drill plugins handler, which allows to update storage plugins configs from the
 * {@link ConfigConstants#STORAGE_PLUGINS_OVERRIDE_CONF} conf file
 *
 * TODO: DRILL-6564: It can be improved with configs versioning and service of creating
 * {@link ConfigConstants#STORAGE_PLUGINS_OVERRIDE_CONF}
 */
public class StoragePluginsHandlerService implements StoragePluginsHandler {
  private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(StoragePluginsHandlerService.class);

  private final LogicalPlanPersistence lpPersistence;
  private final DrillbitContext context;
  private URL pluginsOverrideFileUrl;

  public StoragePluginsHandlerService(DrillbitContext context) {
    this.context = context;
    this.lpPersistence = new LogicalPlanPersistence(context.getConfig(), context.getClasspathScan(),
        new ObjectMapper(new HoconFactory()));
  }

  @Override
  public void loadPlugins(@NotNull PersistentStore<StoragePluginConfig> persistentStore,
                          @Nullable StoragePlugins bootstrapPlugins) {
    // if bootstrapPlugins is not null -- fresh Drill set up
    StoragePlugins pluginsForPersistentStore;

    StoragePlugins newPlugins = getNewStoragePlugins();

    if (newPlugins != null) {
      pluginsForPersistentStore = new StoragePlugins(new HashMap<>());
      Optional.ofNullable(bootstrapPlugins)
          .ifPresent(pluginsForPersistentStore::putAll);

      for (Map.Entry<String, StoragePluginConfig> newPlugin : newPlugins) {
        String pluginName = newPlugin.getKey();
        StoragePluginConfig oldPluginConfig = Optional.ofNullable(bootstrapPlugins)
            .map(plugins -> plugins.getConfig(pluginName))
            .orElse(persistentStore.get(pluginName));
        StoragePluginConfig updatedStatusPluginConfig = updatePluginStatus(oldPluginConfig, newPlugin.getValue());
        pluginsForPersistentStore.put(pluginName, updatedStatusPluginConfig);
      }
    } else {
      pluginsForPersistentStore = bootstrapPlugins;
    }

    // load pluginsForPersistentStore to Persistent Store
    Optional.ofNullable(pluginsForPersistentStore)
        .ifPresent(plugins -> plugins.forEach(plugin -> persistentStore.put(plugin.getKey(), plugin.getValue())));

    if (newPlugins != null) {
      String fileAction = context.getConfig().getString(ACTION_ON_STORAGE_PLUGINS_OVERRIDE_FILE);
      Optional<ActionOnFile> actionOnFile = Arrays.stream(ActionOnFile.values())
          .filter(action -> action.name().equalsIgnoreCase(fileAction))
          .findFirst();
      actionOnFile.ifPresent(action -> action.action(pluginsOverrideFileUrl));
      // TODO: replace with ifPresentOrElse() once the project will be on Java9
      if (!actionOnFile.isPresent()) {
        logger.error("Unknown value {} for {} boot option. Nothing will be done with file.",
            fileAction, ACTION_ON_STORAGE_PLUGINS_OVERRIDE_FILE);
      }
    }
  }

  /**
   * Helper method to identify the enabled status for new storage plugins config. If this status is absent in the updater
   * file, the status is kept from the configs, which are going to be updated
   *
   * @param oldPluginConfig current storage plugin config from Persistent Store or bootstrap config file
   * @param newPluginConfig new storage plugin config
   * @return new storage plugin config with updated enabled status
   */
  private StoragePluginConfig updatePluginStatus(@Nullable StoragePluginConfig oldPluginConfig,
                                                 @NotNull StoragePluginConfig newPluginConfig) {
    if (!newPluginConfig.isEnabledStatusPresent()) {
      boolean newStatus = oldPluginConfig != null && oldPluginConfig.isEnabled();
      newPluginConfig.setEnabled(newStatus);
    }
    return newPluginConfig;
  }

  /**
   * Get the new storage plugins from the {@link ConfigConstants#STORAGE_PLUGINS_OVERRIDE_CONF} file if it exists,
   * null otherwise
   *
   * @return storage plugins
   */
  private StoragePlugins getNewStoragePlugins() {
    Set<URL> urlSet = ClassPathScanner.forResource(ConfigConstants.STORAGE_PLUGINS_OVERRIDE_CONF, false);
    if (!urlSet.isEmpty()) {
      if (urlSet.size() != 1) {
        DrillRuntimeException.format("More than one %s file is placed in Drill's classpath: %s",
            ConfigConstants.STORAGE_PLUGINS_OVERRIDE_CONF, urlSet);
      }
      pluginsOverrideFileUrl = urlSet.iterator().next();
      try {
        String newPluginsData = Resources.toString(pluginsOverrideFileUrl, Charsets.UTF_8);
        return lpPersistence.getMapper().readValue(newPluginsData, StoragePlugins.class);
      } catch (IOException e) {
        logger.error("Failures are obtained while loading %s file. Proceed without update",
            ConfigConstants.STORAGE_PLUGINS_OVERRIDE_CONF, e);
      }
    }
    logger.trace("The {} file is absent. Proceed without updating of the storage plugins configs",
        ConfigConstants.STORAGE_PLUGINS_OVERRIDE_CONF);
    return null;
  }
}
