/*
 * Copyright (C) 2012 The Guava Authors
 *
 * 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.common.testing;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Throwables.throwIfUnchecked;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.fail;

import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Function;
import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import com.google.common.reflect.AbstractInvocationHandler;
import com.google.common.reflect.Reflection;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Tester to ensure forwarding wrapper works by delegating calls to the corresponding method with
 * the same parameters forwarded and return value forwarded back or exception propagated as is.
 *
 * <p>For example:
 *
 * <pre>{@code
 * new ForwardingWrapperTester().testForwarding(Foo.class, new Function<Foo, Foo>() {
 *   public Foo apply(Foo foo) {
 *     return new ForwardingFoo(foo);
 *   }
 * });
 * }</pre>
 *
 * @author Ben Yu
 * @since 14.0
 */
@Beta
@GwtIncompatible
public final class ForwardingWrapperTester {

  private boolean testsEquals = false;

  /**
   * Asks for {@link Object#equals} and {@link Object#hashCode} to be tested. That is, forwarding
   * wrappers of equal instances should be equal.
   */
  public ForwardingWrapperTester includingEquals() {
    this.testsEquals = true;
    return this;
  }

  /**
   * Tests that the forwarding wrapper returned by {@code wrapperFunction} properly forwards method
   * calls with parameters passed as is, return value returned as is, and exceptions propagated as
   * is.
   */
  public <T> void testForwarding(
      Class<T> interfaceType, Function<? super T, ? extends T> wrapperFunction) {
    checkNotNull(wrapperFunction);
    checkArgument(interfaceType.isInterface(), "%s isn't an interface", interfaceType);
    Method[] methods = getMostConcreteMethods(interfaceType);
    AccessibleObject.setAccessible(methods, true);
    for (Method method : methods) {
      // Under java 8, interfaces can have default methods that aren't abstract.
      // No need to verify them.
      // Can't check isDefault() for JDK 7 compatibility.
      if (!Modifier.isAbstract(method.getModifiers())) {
        continue;
      }
      // The interface could be package-private or private.
      // filter out equals/hashCode/toString
      if (method.getName().equals("equals")
          && method.getParameterTypes().length == 1
          && method.getParameterTypes()[0] == Object.class) {
        continue;
      }
      if (method.getName().equals("hashCode") && method.getParameterTypes().length == 0) {
        continue;
      }
      if (method.getName().equals("toString") && method.getParameterTypes().length == 0) {
        continue;
      }
      testSuccessfulForwarding(interfaceType, method, wrapperFunction);
      testExceptionPropagation(interfaceType, method, wrapperFunction);
    }
    if (testsEquals) {
      testEquals(interfaceType, wrapperFunction);
    }
    testToString(interfaceType, wrapperFunction);
  }

  /** Returns the most concrete public methods from {@code type}. */
  private static Method[] getMostConcreteMethods(Class<?> type) {
    Method[] methods = type.getMethods();
    for (int i = 0; i < methods.length; i++) {
      try {
        methods[i] = type.getMethod(methods[i].getName(), methods[i].getParameterTypes());
      } catch (Exception e) {
        throwIfUnchecked(e);
        throw new RuntimeException(e);
      }
    }
    return methods;
  }

  private static <T> void testSuccessfulForwarding(
      Class<T> interfaceType, Method method, Function<? super T, ? extends T> wrapperFunction) {
    new InteractionTester<T>(interfaceType, method).testInteraction(wrapperFunction);
  }

  private static <T> void testExceptionPropagation(
      Class<T> interfaceType, Method method, Function<? super T, ? extends T> wrapperFunction) {
    final RuntimeException exception = new RuntimeException();
    T proxy =
        Reflection.newProxy(
            interfaceType,
            new AbstractInvocationHandler() {
              @Override
              protected Object handleInvocation(Object p, Method m, Object[] args)
                  throws Throwable {
                throw exception;
              }
            });
    T wrapper = wrapperFunction.apply(proxy);
    try {
      method.invoke(wrapper, getParameterValues(method));
      fail(method + " failed to throw exception as is.");
    } catch (InvocationTargetException e) {
      if (exception != e.getCause()) {
        throw new RuntimeException(e);
      }
    } catch (IllegalAccessException e) {
      throw new AssertionError(e);
    }
  }

  private static <T> void testEquals(
      Class<T> interfaceType, Function<? super T, ? extends T> wrapperFunction) {
    FreshValueGenerator generator = new FreshValueGenerator();
    T instance = generator.newFreshProxy(interfaceType);
    new EqualsTester()
        .addEqualityGroup(wrapperFunction.apply(instance), wrapperFunction.apply(instance))
        .addEqualityGroup(wrapperFunction.apply(generator.newFreshProxy(interfaceType)))
        // TODO: add an overload to EqualsTester to print custom error message?
        .testEquals();
  }

  private static <T> void testToString(
      Class<T> interfaceType, Function<? super T, ? extends T> wrapperFunction) {
    T proxy = new FreshValueGenerator().newFreshProxy(interfaceType);
    assertEquals(
        "toString() isn't properly forwarded",
        proxy.toString(),
        wrapperFunction.apply(proxy).toString());
  }

  private static Object[] getParameterValues(Method method) {
    FreshValueGenerator paramValues = new FreshValueGenerator();
    final List<Object> passedArgs = Lists.newArrayList();
    for (Class<?> paramType : method.getParameterTypes()) {
      passedArgs.add(paramValues.generateFresh(paramType));
    }
    return passedArgs.toArray();
  }

  /** Tests a single interaction against a method. */
  private static final class InteractionTester<T> extends AbstractInvocationHandler {

    private final Class<T> interfaceType;
    private final Method method;
    private final Object[] passedArgs;
    private final Object returnValue;
    private final AtomicInteger called = new AtomicInteger();

    InteractionTester(Class<T> interfaceType, Method method) {
      this.interfaceType = interfaceType;
      this.method = method;
      this.passedArgs = getParameterValues(method);
      this.returnValue = new FreshValueGenerator().generateFresh(method.getReturnType());
    }

    @Override
    protected Object handleInvocation(Object p, Method calledMethod, Object[] args)
        throws Throwable {
      assertEquals(method, calledMethod);
      assertEquals(method + " invoked more than once.", 0, called.get());
      for (int i = 0; i < passedArgs.length; i++) {
        assertEquals(
            "Parameter #" + i + " of " + method + " not forwarded", passedArgs[i], args[i]);
      }
      called.getAndIncrement();
      return returnValue;
    }

    void testInteraction(Function<? super T, ? extends T> wrapperFunction) {
      T proxy = Reflection.newProxy(interfaceType, this);
      T wrapper = wrapperFunction.apply(proxy);
      boolean isPossibleChainingCall = interfaceType.isAssignableFrom(method.getReturnType());
      try {
        Object actualReturnValue = method.invoke(wrapper, passedArgs);
        // If we think this might be a 'chaining' call then we allow the return value to either
        // be the wrapper or the returnValue.
        if (!isPossibleChainingCall || wrapper != actualReturnValue) {
          assertEquals(
              "Return value of " + method + " not forwarded", returnValue, actualReturnValue);
        }
      } catch (IllegalAccessException e) {
        throw new RuntimeException(e);
      } catch (InvocationTargetException e) {
        throw Throwables.propagate(e.getCause());
      }
      assertEquals("Failed to forward to " + method, 1, called.get());
    }

    @Override
    public String toString() {
      return "dummy " + interfaceType.getSimpleName();
    }
  }
}
