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

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.hadoop.classification.InterfaceAudience.Private;
import org.apache.tez.dag.api.TezReflectionException;
import org.apache.tez.dag.api.TezUncheckedException;

@Private
public class ReflectionUtils {

  private static final Map<String, Class<?>> CLAZZ_CACHE = new ConcurrentHashMap<String, Class<?>>();

  @Private
  public static Class<?> getClazz(String className) throws TezReflectionException {
    Class<?> clazz = CLAZZ_CACHE.get(className);
    if (clazz == null) {
      try {
        clazz = Class.forName(className, true, Thread.currentThread().getContextClassLoader());
      } catch (ClassNotFoundException e) {
        throw new TezReflectionException("Unable to load class: " + className, e);
      }
    }
    return clazz;
  }

  private static <T> T getNewInstance(Class<T> clazz) throws TezReflectionException {
    T instance;
    try {
      instance = clazz.newInstance();
    } catch (Exception e) {
      throw new TezReflectionException(
          "Unable to instantiate class with 0 arguments: " + clazz.getName(), e);
    }
    return instance;
  }

  private static <T> T getNewInstance(Class<T> clazz, Class<?>[] parameterTypes, Object[] parameters)
    throws TezReflectionException {
    T instance;
    try {
      Constructor<T> constructor = clazz.getConstructor(parameterTypes);
      instance = constructor.newInstance(parameters);
    } catch (Exception e) {
      throw new TezReflectionException(
          "Unable to instantiate class with " + parameters.length + " arguments: " + clazz.getName(), e);
    }
    return instance;
  }

  @Private
  public static <T> T createClazzInstance(String className) throws TezReflectionException {
    Class<?> clazz = getClazz(className);
    @SuppressWarnings("unchecked")
    T instance = (T) getNewInstance(clazz);
    return instance;
  }

  @Private
  public static <T> T createClazzInstance(String className, Class<?>[] parameterTypes, Object[] parameters)
    throws TezReflectionException {
    Class<?> clazz = getClazz(className);
    @SuppressWarnings("unchecked")
    T instance = (T) getNewInstance(clazz, parameterTypes, parameters);
    return instance;
  }

  @Private
  @SuppressWarnings("unchecked")
  public static <T> T invokeMethod(Object target, Method method, Object... args) throws TezReflectionException {
    try {
      return (T) method.invoke(target, args);
    } catch (Exception e) {
      throw new TezReflectionException(e);
    }
  }

  @Private
  public static Method getMethod(Class<?> targetClazz, String methodName, Class<?>... parameterTypes) throws TezReflectionException {
    try {
      return targetClazz.getMethod(methodName, parameterTypes);
    } catch (NoSuchMethodException e) {
      throw new TezReflectionException(e);
    }
  }

  @Private
  public static synchronized void addResourcesToClasspath(List<URL> urls) {
    ClassLoader classLoader = new URLClassLoader(urls.toArray(new URL[urls.size()]), Thread
        .currentThread().getContextClassLoader());
    Thread.currentThread().setContextClassLoader(classLoader);
  }

  // Parameters for addResourcesToSystemClassLoader
  private static final Class<?>[] parameters = new Class[]{URL.class};
  private static Method sysClassLoaderMethod = null;

  @Private
  public static synchronized void addResourcesToSystemClassLoader(List<URL> urls) {
    ClassLoader sysLoader = getSystemClassLoader();
    if (sysClassLoaderMethod == null) {
      Class<?> sysClass = TezClassLoader.class;
      Method method;
      try {
        method = sysClass.getDeclaredMethod("addURL", parameters);
      } catch (SecurityException e) {
        throw new TezUncheckedException("Failed to get handle on method addURL", e);
      } catch (NoSuchMethodException e) {
        throw new TezUncheckedException("Failed to get handle on method addURL", e);
      }
      method.setAccessible(true);
      sysClassLoaderMethod = method;
    }
    for (URL url : urls) {
      try {
        sysClassLoaderMethod.invoke(sysLoader, new Object[] { url });
      } catch (IllegalArgumentException e) {
        throw new TezUncheckedException("Failed to invoke addURL for rsrc: " + url, e);
      } catch (IllegalAccessException e) {
        throw new TezUncheckedException("Failed to invoke addURL for rsrc: " + url, e);
      } catch (InvocationTargetException e) {
        throw new TezUncheckedException("Failed to invoke addURL for rsrc: " + url, e);
      }
    }
  }

  private static ClassLoader getSystemClassLoader() {
    return TezClassLoader.getInstance();
  }
}
