/*
 * 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.common.util;

import java.lang.reflect.Modifier;

import com.google.common.annotations.VisibleForTesting;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtMethod;
import javassist.CtNewMethod;
import javassist.scopedpool.ScopedClassPoolRepository;
import javassist.scopedpool.ScopedClassPoolRepositoryImpl;

public class GuavaPatcher {
  private static final Logger logger = LoggerFactory.getLogger(GuavaPatcher.class);

  private static boolean patchingAttempted;

  public static synchronized void patch() {
    if (!patchingAttempted) {
      patchingAttempted = true;
      patchStopwatch();
      patchCloseables();
      patchFuturesCallback();
    }
  }

  private static boolean patchingSuccessful = true;

  @VisibleForTesting
  static boolean isPatchingSuccessful() {
    return patchingAttempted && patchingSuccessful;
  }

  /**
   * Makes Guava stopwatch look like the old version for compatibility with hbase-server (for test purposes).
   */
  private static void patchStopwatch() {
    try {
      ClassPool cp = getClassPool();
      CtClass cc = cp.get("com.google.common.base.Stopwatch");

      // Expose the constructor for Stopwatch for old libraries who use the pattern new Stopwatch().start().
      for (CtConstructor c : cc.getConstructors()) {
        if (!Modifier.isStatic(c.getModifiers())) {
          c.setModifiers(Modifier.PUBLIC);
        }
      }

      // Add back the Stopwatch.elapsedMillis() method for old consumers.
      CtMethod newMethod = CtNewMethod.make(
          "public long elapsedMillis() { return elapsed(java.util.concurrent.TimeUnit.MILLISECONDS); }", cc);
      cc.addMethod(newMethod);

      // Load the modified class instead of the original.
      cc.toClass();

      logger.info("Google's Stopwatch patched for old HBase Guava version.");
    } catch (Exception e) {
      logUnableToPatchException(e);
    }
  }

  private static void logUnableToPatchException(Exception e) {
    patchingSuccessful = false;
    logger.warn("Unable to patch Guava classes: {}", e.getMessage());
    logger.debug("Exception:", e);
  }

  private static void patchCloseables() {
    try {
      ClassPool cp = getClassPool();
      CtClass cc = cp.get("com.google.common.io.Closeables");

      // Add back the Closeables.closeQuietly() method for old consumers.
      CtMethod newMethod = CtNewMethod.make(
          "public static void closeQuietly(java.io.Closeable closeable) { try{closeable.close();}catch(Exception e){} }",
          cc);
      cc.addMethod(newMethod);

      // Load the modified class instead of the original.
      cc.toClass();

      logger.info("Google's Closeables patched for old HBase Guava version.");
    } catch (Exception e) {
      logUnableToPatchException(e);
    }
  }

  /**
   * Returns {@link javassist.scopedpool.ScopedClassPool} instance which uses the same class loader
   * which was used for loading current class.
   *
   * @return {@link javassist.scopedpool.ScopedClassPool} instance
   */
  private static ClassPool getClassPool() {
    ScopedClassPoolRepository classPoolRepository = ScopedClassPoolRepositoryImpl.getInstance();
    // sets prune flag to false to avoid freezing and pruning classes right after obtaining CtClass instance
    classPoolRepository.setPrune(false);
    return classPoolRepository.createScopedClassPool(GuavaPatcher.class.getClassLoader(), null);
  }

  /**
   * Makes Guava Futures#addCallback look like the old version for compatibility with hadoop-hdfs (for test purposes).
   */
  private static void patchFuturesCallback() {
    try {
      ClassPool cp = getClassPool();
      CtClass cc = cp.get("com.google.common.util.concurrent.Futures");

      // Add back the Futures.addCallback(ListenableFuture future, FutureCallback callback) method for old consumers.
      CtMethod newMethod = CtNewMethod.make(
        "public static void addCallback(" +
                "com.google.common.util.concurrent.ListenableFuture future, " +
                "com.google.common.util.concurrent.FutureCallback callback" +
          ") { addCallback(future, callback, com.google.common.util.concurrent.MoreExecutors.directExecutor()); }", cc);
      cc.addMethod(newMethod);

      // Load the modified class instead of the original.
      cc.toClass();
      logger.info("Google's Futures#addCallback patched for old Hadoop Guava version.");
    } catch (Exception e) {
      logUnableToPatchException(e);
    }
  }
}
