/*
 * Copyright (c) 2014, 2016 Eike Stepper (Loehne, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *    Eike Stepper - initial API and implementation
 *    Christian W. Damus (CEA) - bug 376620: switch on primitive types
 */
package org.eclipse.oomph.util;

import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * Various static helper methods for dealing with Java reflection.
 *
 * @author Eike Stepper
 */
public final class ReflectUtil
{
  private ReflectUtil()
  {
  }

  public static <T> Constructor<T> getConstructor(Class<T> c, Class<?>... parameterTypes)
  {
    try
    {
      Constructor<T> constructor = c.getDeclaredConstructor(parameterTypes);
      makeAccessible(constructor);
      return constructor;
    }
    catch (RuntimeException ex)
    {
      throw ex;
    }
    catch (Exception ex)
    {
      throw new ReflectionException(ex);
    }
  }

  public static <T> T newInstance(Constructor<T> constructor, Object... arguments)
  {
    try
    {
      return constructor.newInstance(arguments);
    }
    catch (RuntimeException ex)
    {
      throw ex;
    }
    catch (InvocationTargetException ex)
    {
      Throwable cause = ex.getCause();
      if (cause != null && "org.eclipse.core.runtime.OperationCanceledException".equals(cause.getClass().getName()))
      {
        throw (RuntimeException)cause;
      }

      throw new ReflectionException(cause);
    }
    catch (Exception ex)
    {
      throw new ReflectionException(ex);
    }
  }

  public static Method getMethod(Object target, String methodName, Class<?>... parameterTypes)
  {
    return getMethod(target.getClass(), methodName, parameterTypes);
  }

  public static Method getMethod(Class<?> c, String methodName, Class<?>... parameterTypes)
  {
    try
    {
      try
      {
        Method method = c.getDeclaredMethod(methodName, parameterTypes);
        makeAccessible(method);
        return method;
      }
      catch (NoSuchMethodException ex)
      {
        Class<?> superclass = c.getSuperclass();
        if (superclass != null)
        {
          return getMethod(superclass, methodName, parameterTypes);
        }

        throw ex;
      }
    }
    catch (RuntimeException ex)
    {
      throw ex;
    }
    catch (Exception ex)
    {
      throw new ReflectionException(ex);
    }
  }

  public static <T> T invokeMethod(Method method, Object target, Object... arguments)
  {
    try
    {
      @SuppressWarnings("unchecked")
      T value = (T)method.invoke(target, arguments);
      return value;
    }
    catch (RuntimeException ex)
    {
      throw ex;
    }
    catch (InvocationTargetException ex)
    {
      Throwable cause = ex.getCause();
      if (cause != null && "org.eclipse.core.runtime.OperationCanceledException".equals(cause.getClass().getName()))
      {
        throw (RuntimeException)cause;
      }

      throw new ReflectionException(cause);
    }
    catch (Exception ex)
    {
      throw new ReflectionException(ex);
    }
  }

  public static <T> T invokeMethod(String methodName, Object target)
  {
    if (target instanceof Class)
    {
      return invokeMethod(getMethod((Class<?>)target, methodName), null);
    }

    return invokeMethod(getMethod(target.getClass(), methodName), target);
  }

  public static Field getField(Class<?> c, String fieldName)
  {
    try
    {
      try
      {
        Field field = c.getDeclaredField(fieldName);
        makeAccessible(field);
        return field;
      }
      catch (NoSuchFieldException ex)
      {
        Class<?> superclass = c.getSuperclass();
        if (superclass != null)
        {
          return getField(superclass, fieldName);
        }

        return null;
      }
    }
    catch (RuntimeException ex)
    {
      throw ex;
    }
    catch (Exception ex)
    {
      throw new ReflectionException(ex);
    }
  }

  public static <T> T getValue(Field field, Object target)
  {
    try
    {
      @SuppressWarnings("unchecked")
      T value = (T)field.get(target);
      return value;
    }
    catch (RuntimeException ex)
    {
      throw ex;
    }
    catch (Exception ex)
    {
      throw new ReflectionException(ex);
    }
  }

  public static <T> T getValue(String fieldName, Object target)
  {
    if (target instanceof Class)
    {
      return getValue(getField((Class<?>)target, fieldName), null);
    }

    return getValue(getField(target.getClass(), fieldName), target);
  }

  public static void setValue(String fieldName, Object target, Object value)
  {
    if (target instanceof Class)
    {
      setValue(getField((Class<?>)target, fieldName), null, value);
    }
    else
    {
      setValue(getField(target.getClass(), fieldName), target, value);
    }
  }

  public static void setValue(Field field, Object target, Object value)
  {
    setValue(field, target, value, false);
  }

  public static void setValue(Field field, Object target, Object value, boolean force)
  {
    try
    {
      if ((field.getModifiers() & Modifier.FINAL) != 0 && force)
      {
        Field modifiersField = Field.class.getDeclaredField("modifiers");
        makeAccessible(modifiersField);
        modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
      }

      Class<?> type = field.getType();
      if (type.isPrimitive())
      {
        if (boolean.class == type)
        {
          field.setBoolean(target, (Boolean)value);
        }
        else if (char.class == type)
        {
          field.setChar(target, (Character)value);
        }
        else if (byte.class == type)
        {
          field.setByte(target, (Byte)value);
        }
        else if (short.class == type)
        {
          field.setShort(target, (Short)value);
        }
        else if (int.class == type)
        {
          field.setInt(target, (Integer)value);
        }
        else if (long.class == type)
        {
          field.setLong(target, (Long)value);
        }
        else if (float.class == type)
        {
          field.setFloat(target, (Float)value);
        }
        else if (double.class == type)
        {
          field.setDouble(target, (Double)value);
        }
      }
      else
      {
        field.set(target, value);
      }
    }
    catch (RuntimeException ex)
    {
      throw ex;
    }
    catch (Exception ex)
    {
      throw new ReflectionException(ex);
    }
  }

  private static <T> void makeAccessible(AccessibleObject accessibleObject)
  {
    if (!accessibleObject.isAccessible())
    {
      accessibleObject.setAccessible(true);
    }
  }

  /**
   * @author Eike Stepper
   */
  public static class ReflectionException extends RuntimeException
  {
    private static final long serialVersionUID = 1L;

    public ReflectionException()
    {
    }

    public ReflectionException(String message, Throwable cause)
    {
      super(message, cause);
    }

    public ReflectionException(String message)
    {
      super(message);
    }

    public ReflectionException(Throwable cause)
    {
      super(cause);
    }
  }
}
