/*
 * Copyright 2008 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.dev.javac;

import com.google.gwt.dev.util.collect.Maps;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Map;

/**
 * Creates proxies for annotation objects that...
 */
class AnnotationProxyFactory {
  /**
   * {@link InvocationHandler} implementation used by all
   * {@link java.lang.annotation.Annotation Annotation} proxies created by the
   * {@link TypeOracle}.
   */
  private static class AnnotationProxyInvocationHandler implements
      InvocationHandler {

    /**
     * Returns <code>true</code> if the expected return type is assignable
     * from the actual return type or if the expected return type is a primitive
     * and the actual return type is the corresponding wrapper type.
     */
    private static boolean isValidReturnType(Class<?> expectedReturnType,
        Class<? extends Object> actualReturnType) {
      if (expectedReturnType.isAssignableFrom(actualReturnType)) {
        return true;
      }

      if (expectedReturnType.isPrimitive()) {
        if (expectedReturnType == boolean.class) {
          return actualReturnType == Boolean.class;
        } else if (expectedReturnType == byte.class) {
          return actualReturnType == Byte.class;
        } else if (expectedReturnType == char.class) {
          return actualReturnType == Character.class;
        } else if (expectedReturnType == double.class) {
          return actualReturnType == Double.class;
        } else if (expectedReturnType == float.class) {
          return actualReturnType == Float.class;
        } else if (expectedReturnType == int.class) {
          return actualReturnType == Integer.class;
        } else if (expectedReturnType == long.class) {
          return actualReturnType == Long.class;
        } else if (expectedReturnType == short.class) {
          return actualReturnType == Short.class;
        }
      }

      return false;
    }

    /**
     * The resolved class of this annotation.
     */
    private Class<? extends Annotation> annotationClass;

    /**
     * Maps method names onto values. Note that methods on annotation types
     * cannot be overloaded because they have zero arguments.
     */
    private final Map<String, Object> identifierToValue;

    /**
     * A reference to the enclosing proxy object.
     */
    private Annotation proxy;

    public AnnotationProxyInvocationHandler(
        Map<String, Object> identifierToValue,
        Class<? extends Annotation> annotationClass) {
      this.identifierToValue = Maps.normalizeUnmodifiable(identifierToValue);
      this.annotationClass = annotationClass;
    }

    @Override
    public boolean equals(Object other) {
      // This is not actually an asymmetric equals implementation, as this
      // method gets called for our proxy instance rather than on the handler
      // itself.
      if (proxy == other) {
        return true;
      }

      if (!(other instanceof Annotation)) {
        return false;
      }

      Annotation otherAnnotation = (Annotation) other;
      if (annotationClass != otherAnnotation.annotationType()) {
        return false;
      }

      try {
        for (Method method : annotationClass.getDeclaredMethods()) {
          Object myVal = method.invoke(proxy);
          Object otherVal = method.invoke(other);

          if (myVal instanceof Object[]) {
            if (!Arrays.equals((Object[]) myVal, (Object[]) otherVal)) {
              return false;
            }
          } else if (myVal instanceof boolean[]) {
            if (!Arrays.equals((boolean[]) myVal, (boolean[]) otherVal)) {
              return false;
            }
          } else if (myVal instanceof byte[]) {
            if (!Arrays.equals((byte[]) myVal, (byte[]) otherVal)) {
              return false;
            }
          } else if (myVal instanceof char[]) {
            if (!Arrays.equals((char[]) myVal, (char[]) otherVal)) {
              return false;
            }
          } else if (myVal instanceof short[]) {
            if (!Arrays.equals((short[]) myVal, (short[]) otherVal)) {
              return false;
            }
          } else if (myVal instanceof int[]) {
            if (!Arrays.equals((int[]) myVal, (int[]) otherVal)) {
              return false;
            }
          } else if (myVal instanceof long[]) {
            if (!Arrays.equals((long[]) myVal, (long[]) otherVal)) {
              return false;
            }
          } else if (myVal instanceof float[]) {
            if (!Arrays.equals((float[]) myVal, (float[]) otherVal)) {
              return false;
            }
          } else if (myVal instanceof double[]) {
            if (!Arrays.equals((double[]) myVal, (double[]) otherVal)) {
              return false;
            }
          } else {
            if (!myVal.equals(otherVal)) {
              return false;
            }
          }
        }
      } catch (IllegalArgumentException e) {
        throw new RuntimeException(e);
      } catch (IllegalAccessException e) {
        throw new RuntimeException(e);
      } catch (InvocationTargetException e) {
        throw new RuntimeException(e.getTargetException());
      }
      return true;
    }

    @Override
    public int hashCode() {
      int sum = 0;
      try {
        for (Method method : annotationClass.getDeclaredMethods()) {
          Object myVal = method.invoke(proxy);
          int memberHash;
          if (myVal instanceof Object[]) {
            memberHash = Arrays.hashCode((Object[]) myVal);
          } else if (myVal instanceof boolean[]) {
            memberHash = Arrays.hashCode((boolean[]) myVal);
          } else if (myVal instanceof byte[]) {
            memberHash = Arrays.hashCode((byte[]) myVal);
          } else if (myVal instanceof char[]) {
            memberHash = Arrays.hashCode((char[]) myVal);
          } else if (myVal instanceof short[]) {
            memberHash = Arrays.hashCode((short[]) myVal);
          } else if (myVal instanceof int[]) {
            memberHash = Arrays.hashCode((int[]) myVal);
          } else if (myVal instanceof long[]) {
            memberHash = Arrays.hashCode((long[]) myVal);
          } else if (myVal instanceof float[]) {
            memberHash = Arrays.hashCode((float[]) myVal);
          } else if (myVal instanceof double[]) {
            memberHash = Arrays.hashCode((double[]) myVal);
          } else {
            memberHash = myVal.hashCode();
          }
          // See doc for Annotation.hashCode.
          memberHash ^= 127 * method.getName().hashCode();
          sum += memberHash;
        }
      } catch (IllegalArgumentException e) {
        throw new RuntimeException(e);
      } catch (IllegalAccessException e) {
        throw new RuntimeException(e);
      } catch (InvocationTargetException e) {
        throw new RuntimeException(e.getTargetException());
      }
      return sum;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object,
     *      java.lang.reflect.Method, java.lang.Object[])
     */
    public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable {

      Object value = null;
      if (args == null || args.length == 0) {
        // A no-arg method, try to process as an annotation method.
        String name = method.getName();
        if (identifierToValue.containsKey(name)) {
          // The value was explicitly provided
          value = identifierToValue.get(name);
          assert (value != null);
        } else {
          if ("annotationType".equals(method.getName())) {
            value = annotationClass;
          } else {
            value = method.getDefaultValue();
          }
        }
        if (value != null) {
          assert (isValidReturnType(method.getReturnType(), value.getClass()));
          return value;
        }
      }

      /*
       * Maybe it's an Object method, just delegate to myself.
       */
      return method.invoke(this, args);
    }

    public void setProxy(Annotation proxy) {
      this.proxy = proxy;
    }

    @Override
    public String toString() {
      final StringBuilder msg = new StringBuilder();
      String qualifiedSourceName = annotationClass.getName().replace('$', '.');
      msg.append('@').append(qualifiedSourceName).append('(');
      boolean first = true;
      try {
        for (Method method : annotationClass.getDeclaredMethods()) {
          if (first) {
            first = false;
          } else {
            msg.append(", ");
          }
          msg.append(method.getName()).append('=');
          Object myVal = method.invoke(proxy);
          if (myVal.getClass().isArray()) {
            msg.append(java.util.Arrays.deepToString((Object[]) myVal));
          } else {
            msg.append(myVal);
          }
        }
      } catch (IllegalArgumentException e) {
        throw new RuntimeException(e);
      } catch (IllegalAccessException e) {
        throw new RuntimeException(e);
      } catch (InvocationTargetException e) {
        throw new RuntimeException(e.getTargetException());
      }
      msg.append(')');
      return msg.toString();
    }
  }

  public static Annotation create(Class<? extends Annotation> annotationClass,
      Map<String, Object> identifierToValue) {
    AnnotationProxyInvocationHandler annotationInvocationHandler = new AnnotationProxyInvocationHandler(
        identifierToValue, annotationClass);
    Annotation proxy = (Annotation) Proxy.newProxyInstance(
        Thread.currentThread().getContextClassLoader(), new Class<?>[] {
            java.lang.annotation.Annotation.class, annotationClass},
        annotationInvocationHandler);
    annotationInvocationHandler.setProxy(proxy);
    return proxy;
  }
}