/*
 * 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.planner.sql.handlers;

import com.google.common.collect.Lists;
import org.apache.calcite.sql.SqlCharStringLiteral;
import org.apache.calcite.sql.SqlNode;
import org.apache.drill.common.exceptions.DrillRuntimeException;
import org.apache.drill.common.exceptions.UserException;
import org.apache.drill.exec.ExecConstants;
import org.apache.drill.exec.exception.VersionMismatchException;
import org.apache.drill.exec.expr.fn.registry.RemoteFunctionRegistry;
import org.apache.drill.exec.physical.PhysicalPlan;
import org.apache.drill.exec.planner.sql.DirectPlan;
import org.apache.drill.exec.planner.sql.parser.SqlDropFunction;
import org.apache.drill.exec.proto.UserBitShared.Jar;
import org.apache.drill.exec.proto.UserBitShared.Registry;
import org.apache.drill.exec.store.sys.store.DataChangeVersion;
import org.apache.drill.exec.util.JarUtil;
import org.apache.drill.exec.work.foreman.ForemanSetupException;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.List;

public class DropFunctionHandler extends DefaultSqlHandler {
  private static Logger logger = LoggerFactory.getLogger(DropFunctionHandler.class);

  public DropFunctionHandler(SqlHandlerConfig config) {
    super(config);
  }

  /**
   * Unregisters UDFs dynamically. Process consists of several steps:
   * <ol>
   * <li>Registering jar in jar registry to ensure that several jars with the same name is not being unregistered.</li>
   * <li>Starts remote unregistration process, gets list of all jars and excludes jar to be deleted.</li>
   * <li>Signals drill bits to start local unregistration process.</li>
   * <li>Removes source and binary jars from registry area.</li>
   * </ol>
   *
   * UDFs unregistration is allowed only if dynamic UDFs support is enabled.
   * Only jars registered dynamically can be unregistered,
   * built-in functions loaded at start up are not allowed to be unregistered.
   *
   * Limitation: before jar unregistration make sure no one is using functions from this jar.
   * There is no guarantee that running queries will finish successfully or give correct result.
   *
   * @return - Single row indicating list of unregistered UDFs, raise exception otherwise
   */
  @Override
  public PhysicalPlan getPlan(SqlNode sqlNode) throws ForemanSetupException, IOException {
    if (!context.getOption(ExecConstants.DYNAMIC_UDF_SUPPORT_ENABLED).bool_val) {
      throw UserException.validationError()
          .message("Dynamic UDFs support is disabled.")
          .build(logger);
    }

    SqlDropFunction node = unwrap(sqlNode, SqlDropFunction.class);
    String jarName = ((SqlCharStringLiteral) node.getJar()).toValue();
    RemoteFunctionRegistry remoteFunctionRegistry = context.getRemoteFunctionRegistry();

    boolean inProgress = false;
    try {
      final String action = remoteFunctionRegistry.addToJars(jarName, RemoteFunctionRegistry.Action.UNREGISTRATION);
      if (!(inProgress = action == null)) {
        return DirectPlan.createDirectPlan(context, false, String.format("Jar with %s name is used. Action: %s", jarName, action));
      }

      Jar deletedJar = unregister(jarName, remoteFunctionRegistry);
      if (deletedJar == null) {
        return DirectPlan.createDirectPlan(context, false, String.format("Jar %s is not registered in remote registry", jarName));
      }
      remoteFunctionRegistry.submitForUnregistration(jarName);

      removeJarFromArea(jarName, remoteFunctionRegistry.getFs(), remoteFunctionRegistry.getRegistryArea());
      removeJarFromArea(JarUtil.getSourceName(jarName), remoteFunctionRegistry.getFs(), remoteFunctionRegistry.getRegistryArea());

      return DirectPlan.createDirectPlan(context, true,
          String.format("The following UDFs in jar %s have been unregistered:\n%s", jarName, deletedJar.getFunctionSignatureList()));

    } catch (Exception e) {
      logger.error("Error during UDF unregistration", e);
      return DirectPlan.createDirectPlan(context, false, e.getMessage());
    } finally {
      if (inProgress) {
        remoteFunctionRegistry.finishUnregistration(jarName);
        remoteFunctionRegistry.removeFromJars(jarName);
      }
    }
  }

  /**
   * Gets remote function registry with version.
   * Version is used to ensure that we update the same registry we removed jars from.
   * Looks for a jar to be deleted, if founds one,
   * attempts to update remote registry with list of jars, that excludes jar to be deleted.
   * If during update {@link VersionMismatchException} was detected,
   * attempts to repeat unregistration process till retry attempts exceeds the limit.
   * If retry attempts number hits 0, throws exception that failed to update remote function registry.
   *
   * @param jarName jar name
   * @param remoteFunctionRegistry remote function registry
   * @return jar that was unregistered, null otherwise
   */
  private Jar unregister(String jarName, RemoteFunctionRegistry remoteFunctionRegistry) {
    int retryAttempts = remoteFunctionRegistry.getRetryAttempts();
    while (retryAttempts >= 0) {
      DataChangeVersion version = new DataChangeVersion();
      Registry registry = remoteFunctionRegistry.getRegistry(version);
      Jar jarToBeDeleted = null;
      List<Jar> jars = Lists.newArrayList();
      for (Jar j : registry.getJarList()) {
        if (j.getName().equals(jarName)) {
          jarToBeDeleted = j;
        } else {
          jars.add(j);
        }
      }
      if (jarToBeDeleted == null) {
        return null;
      }
      Registry updatedRegistry = Registry.newBuilder().addAllJar(jars).build();
      try {
        remoteFunctionRegistry.updateRegistry(updatedRegistry, version);
        return jarToBeDeleted;
      } catch (VersionMismatchException ex) {
        logger.debug("Failed to update function registry during unregistration, version mismatch was detected.", ex);
        retryAttempts--;
      }
    }
    throw new DrillRuntimeException("Failed to update remote function registry. Exceeded retry attempts limit.");
  }

  /**
   * Removes jar from indicated area, in case of error log it and proceeds.
   *
   * @param jarName jar name
   * @param fs file system
   * @param area path to area
   */
  private void removeJarFromArea(String jarName, FileSystem fs, Path area) {
    try {
      fs.delete(new Path(area, jarName), false);
    } catch (IOException e) {
      logger.error("Error removing jar {} from area {}", jarName, area.toUri().getPath());
    }
  }
}
