/*
 * Copyright 2009 Google Inc.
 *
 * Licensed 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 com.google.gwt.uibinder.rebind;

import com.google.gwt.core.ext.typeinfo.HasAnnotations;
import com.google.gwt.core.ext.typeinfo.HasTypeParameters;
import com.google.gwt.core.ext.typeinfo.JAbstractMethod;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JConstructor;
import com.google.gwt.core.ext.typeinfo.JField;
import com.google.gwt.core.ext.typeinfo.JMethod;
import com.google.gwt.core.ext.typeinfo.JParameter;
import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
import com.google.gwt.core.ext.typeinfo.JType;

import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.isA;

import org.easymock.IAnswer;
import org.easymock.classextension.EasyMock;

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.GenericDeclaration;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Creates stub adapters for GWT reflection using EasyMock.
 * This takes in a real java reflection class and returns a JClassType which
 * forwards all its method calls to the equivalent java reflection methods.
 * <p>
 * Most reflections are done lazily (only when the method is actually called),
 * specially those which potentially require mocking a new class / method /
 * field / parameter / constructor / etc.
 * <p>
 * The support for the typeinfo API is still incomplete, and in fact will
 * always be in some way since Java doesn't support all the reflections that
 * GWT's typeinfo does.
 * <p>
 * TODO: With a bit of generalization, this class should make its way
 * to core/src/com/google/gwt/junit
 *
 * To make it public we need to...
 * <ol>
 * <li>implement the missing parts and TODOs (e.g. generics)
 * <li>add tests to it (even though it's a testing utility, it does need
 * tests, specially for cases like inner and anonymous classes, generic
 * parameters, etc.)
 * <li>decide what to do with the parts of JType reflection that java doesn't
 * have an equivalent for - e.g. parameter names. This may involve making a
 * slightly more complex API to inject those values.
 * </ol>
 */
public class JClassTypeAdapter {

  private final Map<Class<?>, JClassType> adaptedClasses =
    new HashMap<Class<?>, JClassType>();
  private final List<Object> allMocks = new ArrayList<Object>();

  public void verifyAll() {
    EasyMock.verify(allMocks.toArray());
  }

  /**
   * Creates a mock GWT class type for the given Java class.
   *
   * @param clazz the java class
   * @return the gwt class
   */
  public JClassType adaptJavaClass(final Class<?> clazz) {
    if (clazz.isPrimitive()) {
      throw new RuntimeException(
          "Only classes can be passed to adaptJavaClass");
    }

    // First try the cache (also avoids infinite recursion if a type references
    // itself).
    JClassType type = adaptedClasses.get(clazz);
    if (type != null) {
      return type;
    }

    // Create and put in the cache
    type = createMock(JClassType.class);
    final JClassType finalType = type;
    adaptedClasses.put(clazz, type);

    // Adds behaviour for annotations and generics
    addAnnotationBehaviour(clazz, type);

    // TODO(rdamazio): Add generics behaviour

    // Add behaviour for getting methods
    expect(type.getMethods()).andStubAnswer(new IAnswer<JMethod[]>() {
      public JMethod[] answer() throws Throwable {
        // TODO(rdamazio): Check behaviour for parent methods
        Method[] realMethods = clazz.getDeclaredMethods();
        JMethod[] methods = new JMethod[realMethods.length];
        for (int i = 0; i < realMethods.length; i++) {
          methods[i] = adaptMethod(realMethods[i], finalType);
        }
        return methods;
      }
    });

    // Add behaviour for getting constructors
    expect(type.getConstructors()).andStubAnswer(new IAnswer<JConstructor[]>() {
      public JConstructor[] answer() throws Throwable {
        Constructor<?>[] realConstructors = clazz.getDeclaredConstructors();
        JConstructor[] constructors = new JConstructor[realConstructors.length];
        for (int i = 0; i < realConstructors.length; i++) {
          constructors[i] = adaptConstructor(realConstructors[i], finalType);
        }
        return constructors;
      }
    });

    // Add behaviour for getting fields
    expect(type.getFields()).andStubAnswer(new IAnswer<JField[]>() {
      public JField[] answer() throws Throwable {
        Field[] realFields = clazz.getDeclaredFields();
        JField[] fields = new JField[realFields.length];
        for (int i = 0; i < realFields.length; i++) {
          fields[i] = adaptField(realFields[i], finalType);
        }
        return fields;
      }
    });

    // Add behaviour for getting names
    expect(type.getName()).andStubReturn(clazz.getName());
    expect(type.getQualifiedSourceName()).andStubReturn(
        clazz.getCanonicalName());
    expect(type.getSimpleSourceName()).andStubReturn(clazz.getSimpleName());

    // Add modifier behaviour
    int modifiers = clazz.getModifiers();
    expect(type.isAbstract()).andStubReturn(Modifier.isAbstract(modifiers));
    expect(type.isFinal()).andStubReturn(Modifier.isFinal(modifiers));
    expect(type.isPublic()).andStubReturn(Modifier.isPublic(modifiers));
    expect(type.isProtected()).andStubReturn(Modifier.isProtected(modifiers));
    expect(type.isPrivate()).andStubReturn(Modifier.isPrivate(modifiers));

    // Add conversion behaviours
    expect(type.isArray()).andStubReturn(null);
    expect(type.isEnum()).andStubReturn(null);
    expect(type.isPrimitive()).andStubReturn(null);
    expect(type.isClassOrInterface()).andStubReturn(type);
    if (clazz.isInterface()) {
      expect(type.isClass()).andStubReturn(null);
      expect(type.isInterface()).andStubReturn(type);
    } else {
      expect(type.isClass()).andStubReturn(type);
      expect(type.isInterface()).andStubReturn(null);
    }
    expect(type.getEnclosingType()).andStubAnswer(new IAnswer<JClassType>() {
      public JClassType answer() throws Throwable {
        Class<?> enclosingClass = clazz.getEnclosingClass();
        if (enclosingClass == null) {
          return null;
        }

        return adaptJavaClass(enclosingClass);
      }
    });
    expect(type.getSuperclass()).andStubAnswer(new IAnswer<JClassType>() {
      public JClassType answer() throws Throwable {
        Class<?> superclass = clazz.getSuperclass();
        if (superclass == null) {
          return null;
        }

        return adaptJavaClass(superclass);
      }
    });

    // TODO(rdamazio): Mock out other methods as needed
    // TODO(rdamazio): Figure out what to do with reflections that GWT allows
    //                 but Java doesn't

    EasyMock.replay(type);
    return type;
  }

  /**
   * Creates a mock GWT field for the given Java field.
   *
   * @param realField the java field
   * @param enclosingType the GWT enclosing type
   * @return the GWT field
   */
  public JField adaptField(final Field realField, JClassType enclosingType) {
    JField field = createMock(JField.class);

    addAnnotationBehaviour(realField, field);

    expect(field.getType()).andStubAnswer(new IAnswer<JType>() {
      public JType answer() throws Throwable {
        return adaptType(realField.getType());
      }
    });

    expect(field.getEnclosingType()).andStubReturn(enclosingType);
    expect(field.getName()).andStubReturn(realField.getName());

    EasyMock.replay(field);
    return field;
  }

  /**
   * Creates a mock GWT constructor for the given java constructor.
   *
   * @param realConstructor the java constructor
   * @param enclosingType the type to which the constructor belongs
   * @return the GWT constructor
   */
  private JConstructor adaptConstructor(final Constructor<?> realConstructor,
      JClassType enclosingType) {
    final JConstructor constructor = createMock(JConstructor.class);

    addCommonAbstractMethodBehaviour(realConstructor, constructor,
        enclosingType);
    addAnnotationBehaviour(realConstructor, constructor);

    // Parameters
    expect(constructor.getParameters()).andStubAnswer(
        new IAnswer<JParameter[]>() {
          public JParameter[] answer() throws Throwable {
            return adaptParameters(realConstructor.getParameterTypes(),
                realConstructor.getParameterAnnotations(), constructor);
          }
        });

    // Thrown exceptions
    expect(constructor.getThrows()).andStubAnswer(
        new IAnswer<JType[]>() {
          public JType[] answer() throws Throwable {
            Class<?>[] realThrows = realConstructor.getExceptionTypes();
            JType[] gwtThrows = new JType[realThrows.length];
            for (int i = 0; i < realThrows.length; i++) {
              gwtThrows[i] = adaptType(realThrows[i]);
            }
            return gwtThrows;
          }
        });

    EasyMock.replay(constructor);
    return constructor;
  }

  /**
   * Creates a mock GWT method for the given java method.
   *
   * @param realMethod the java method
   * @param enclosingType the type to which the method belongs
   * @return the GWT method
   */
  private JMethod adaptMethod(final Method realMethod,
      JClassType enclosingType) {
    // TODO(rdamazio): ensure a single instance per method per class
    final JMethod method = createMock(JMethod.class);

    addCommonAbstractMethodBehaviour(realMethod, method, enclosingType);
    addAnnotationBehaviour(realMethod, method);
    addGenericsBehaviour(realMethod, method);

    expect(method.isStatic()).andStubReturn(
        Modifier.isStatic(realMethod.getModifiers()));

    // Return type
    expect(method.getReturnType()).andStubAnswer(new IAnswer<JType>() {
      public JType answer() throws Throwable {
        return adaptType(realMethod.getReturnType());
      }
    });

    // Parameters
    expect(method.getParameters()).andStubAnswer(new IAnswer<JParameter[]>() {
      public JParameter[] answer() throws Throwable {
        return adaptParameters(realMethod.getParameterTypes(),
            realMethod.getParameterAnnotations(), method);
      }
    });

    // Thrown exceptions
    expect(method.getThrows()).andStubAnswer(new IAnswer<JType[]>() {
      public JType[] answer() throws Throwable {
        Class<?>[] realThrows = realMethod.getExceptionTypes();
        JType[] gwtThrows = new JType[realThrows.length];
        for (int i = 0; i < realThrows.length; i++) {
          gwtThrows[i] = adaptType(realThrows[i]);
        }
        return gwtThrows;
      }
    });

    EasyMock.replay(method);
    return method;
  }

  /**
   * Creates an array of mock GWT parameters for the given array of java
   * parameters.
   *
   * @param parameterTypes the types of the parameters
   * @param parameterAnnotations the list of annotations for each parameter
   * @param method the method or constructor to which the parameters belong
   * @return an array of GWT parameters
   */
  @SuppressWarnings("unchecked")
  protected JParameter[] adaptParameters(Class<?>[] parameterTypes,
      Annotation[][] parameterAnnotations, JAbstractMethod method) {
    JParameter[] parameters = new JParameter[parameterTypes.length];
    for (int i = 0; i < parameterTypes.length; i++) {
      final Class<?> realParameterType = parameterTypes[i];
      JParameter parameter = createMock(JParameter.class);
      parameters[i] = parameter;

      // TODO(rdamazio): getName() has no plain java equivalent.
      //                 Perhaps compiling with -g:vars ?

      expect(parameter.getEnclosingMethod()).andStubReturn(method);
      expect(parameter.getType()).andStubAnswer(new IAnswer<JType>() {
        public JType answer() throws Throwable {
          return adaptType(realParameterType);
        }
      });

      // Add annotation behaviour
      final Annotation[] annotations = parameterAnnotations[i];

      expect(parameter.isAnnotationPresent(isA(Class.class))).andStubAnswer(
          new IAnswer<Boolean>() {
            public Boolean answer() throws Throwable {
              Class<? extends Annotation> annotationClass =
                  (Class<? extends Annotation>)
                  EasyMock.getCurrentArguments()[0];
              for (Annotation annotation : annotations) {
                if (annotation.equals(annotationClass)) {
                  return true;
                }
              }
              return false;
            }
          });

      expect(parameter.getAnnotation(isA(Class.class))).andStubAnswer(
          new IAnswer<Annotation>() {
            public Annotation answer() throws Throwable {
              Class<? extends Annotation> annotationClass =
                  (Class<? extends Annotation>)
                  EasyMock.getCurrentArguments()[0];
              for (Annotation annotation : annotations) {
                if (annotation.equals(annotationClass)) {
                  return annotation;
                }
              }
              return null;
            }
          });

      EasyMock.replay(parameter);
    }

    return parameters;
  }

  /**
   * Creates a GWT mock type for the given java type.
   * The type can be a class or a primitive type.
   *
   * @param type the java type
   * @return the GWT type
   */
  private JType adaptType(Class<?> type) {
    if (!type.isPrimitive()) {
      return adaptJavaClass(type);
    } else {
      return adaptPrimitiveType(type);
    }
  }

  /**
   * Returns the GWT primitive type for the given java primitive type.
   *
   * @param type the java primitive type
   * @return the GWT primitive equivalent
   */
  private JType adaptPrimitiveType(Class<?> type) {
    if (boolean.class.equals(type)) { return JPrimitiveType.BOOLEAN; }
    if (int.class.equals(type)) { return JPrimitiveType.INT; }
    if (char.class.equals(type)) { return JPrimitiveType.CHAR; }
    if (byte.class.equals(type)) { return JPrimitiveType.BYTE; }
    if (long.class.equals(type)) { return JPrimitiveType.LONG; }
    if (short.class.equals(type)) { return JPrimitiveType.SHORT; }
    if (float.class.equals(type)) { return JPrimitiveType.FLOAT; }
    if (double.class.equals(type)) { return JPrimitiveType.DOUBLE; }
    if (void.class.equals(type)) { return JPrimitiveType.VOID; }

    throw new IllegalArgumentException(
        "Invalid primitive type: " + type.getName());
  }

  /**
   * Adds expectations common to all method types (methods and constructors).
   *
   * @param realMember the java method
   * @param member the mock GWT method
   * @param enclosingType the type to which the method belongs
   */
  private void addCommonAbstractMethodBehaviour(Member realMember,
      JAbstractMethod member, JClassType enclosingType) {
    // Attributes
    int modifiers = realMember.getModifiers();
    expect(member.isPublic()).andStubReturn(Modifier.isPublic(modifiers));
    expect(member.isProtected()).andStubReturn(Modifier.isProtected(modifiers));
    expect(member.isPrivate()).andStubReturn(Modifier.isPrivate(modifiers));
    expect(member.getName()).andStubReturn(realMember.getName());
    expect(member.getEnclosingType()).andStubReturn(enclosingType);
  }

  /**
   * Adds expectations for getting annotations from elements (methods, classes,
   * parameters, etc.).
   *
   * @param realElement the java element which contains annotations
   * @param element the mock GWT element which contains annotations
   */
  @SuppressWarnings("unchecked")
  private void addAnnotationBehaviour(final AnnotatedElement realElement,
      final HasAnnotations element) {
    expect(element.isAnnotationPresent(isA(Class.class))).andStubAnswer(
        new IAnswer<Boolean>() {
          public Boolean answer() throws Throwable {
            Class<? extends Annotation> annotationClass =
                (Class<? extends Annotation>) EasyMock.getCurrentArguments()[0];
            return realElement.isAnnotationPresent(annotationClass);
          }
        });

    expect(element.getAnnotation(isA(Class.class))).andStubAnswer(
        new IAnswer<Annotation>() {
          public Annotation answer() throws Throwable {
            Class<? extends Annotation> annotationClass =
                (Class<? extends Annotation>) EasyMock.getCurrentArguments()[0];
            return realElement.getAnnotation(annotationClass);
          }
        });
  }

  /**
   * Adds expectations for getting generics types.
   *
   * @param realGeneric the java generic declaration
   * @param generic the mock GWT generic declaration
   */
  private void addGenericsBehaviour(final GenericDeclaration realGeneric,
      final HasTypeParameters generic) {
    // TODO(rdamazio): Implement when necessary
  }

  /**
   * Creates a mock of the given class and adds it to the {@link #allMocks}
   * member list.
   *
   * @param <T> the type of the mock
   * @param clazz the class of the mock
   * @return the mock
   */
  private <T> T createMock(Class<T> clazz) {
    T mock = EasyMock.createMock(clazz);
    allMocks.add(mock);
    return mock;
  }
}
