/*
 * Copyright 2016 The Bazel Authors. All rights reserved.
 *
 * 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.idea.blaze.base.model.blaze.deepequalstester;

import com.google.common.collect.Lists;
import com.google.idea.blaze.base.model.blaze.deepequalstester.Examples.ExampleNotFoundException;
import com.google.idea.blaze.base.model.blaze.deepequalstester.Examples.Pair;
import com.google.idea.blaze.base.model.blaze.deepequalstester.ReachabilityAnalysis.ReachableClasses;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import org.jetbrains.annotations.NotNull;
import org.junit.Assert;

/** Used to test equals implementations */
public final class DeepEqualsTester {

  /** Thrown when the test fails */
  public static class TestCorrectnessException extends Exception {

    public TestCorrectnessException(String s) {
      super(s);
    }
  }

  /**
   * Ensure that the equals method of {@param rootObject} uses all of its fields in its comparison.
   * Recurse into every field of {@param rootObject} to ensure that they also use all of their
   * fields in their equals method. Continue recursion until primitives are hit.
   *
   * <p>If multiple failures could occur, there is no guarantee that they will always occur in the
   * same order. Only the first failure is reported.
   *
   * @param rootObject an example instantiation of the class we want to test for deep equals sanity.
   *     The object must be a standard java object (no collections, no arrays, no primitives). If
   *     you would like to pass these types in, you should put them in a box first.
   * @param examples examples of objects to use for comparison. This should contain a pair of
   *     examples for every type that could be reachable from the root object. This value may be
   *     mutated by this test.
   */
  public static <T extends Serializable> void doDeepEqualsAndHashTest(
      @NotNull T rootObject, Examples examples)
      throws InstantiationException, IllegalAccessException, NoSuchFieldException,
          ExampleNotFoundException, TestCorrectnessException {
    ReachableClasses reachableClasses = new ReachableClasses();

    try {
      ArrayList<String> initialPath = Lists.newArrayList("root");
      // Find all of the classes reachable from the root object. This is not sound since it
      // ignores subtypes (or supertypes) that could be used
      ReachabilityAnalysis.computeReachableFromObject(
          rootObject, rootObject.getClass(), initialPath, reachableClasses);
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    }

    // Add the root object to our list of reachable classes so we can do all the testing in one
    // loop
    reachableClasses.addPath(rootObject.getClass(), Lists.newArrayList("root"));
    // In our situations, we never need a second example of the root object
    examples.addExample(rootObject.getClass(), rootObject, rootObject);
    // For each reachable class, do a shallow equals test where we change each value of the
    // object one at a time and test for equality
    for (Class<? extends Serializable> clazz : reachableClasses.getClasses()) {
      Serializable workitem = (Serializable) examples.getExamples(clazz).getFirst();
      testShallowEquals(workitem, reachableClasses, examples);
    }
  }

  private static String getFailureMessage(String method, Field field, List<String> examplePath) {
    StringBuilder sb = new StringBuilder();
    sb.append(field.toString())
        .append(" is not represented in it's parent's ")
        .append(method)
        .append(" method\n");
    for (String path : examplePath) {
      sb.append("\t").append(path).append("\n");
    }
    sb.append("\n");
    return sb.toString();
  }

  /**
   * Mutate each field in the object one at a time and test for equality of the object. Assert a
   * failure if any mutation doesn't result in the two objects not being equal
   */
  private static <T extends Serializable> void testShallowEquals(
      @NotNull T original, ReachableClasses reachableClasses, Examples examples)
      throws ExampleNotFoundException, IllegalAccessException, TestCorrectnessException {
    T clone = (T) DeepEqualsTesterUtil.cloneWithSerialization(original);
    List<Field> allFields = DeepEqualsTesterUtil.getAllFields(original.getClass());
    for (Field field : allFields) {
      if (!Modifier.isStatic(field.getModifiers())) {
        field.setAccessible(true);
        Pair<?, ?> examplesPair =
            examples.getExamples((Class<? extends Serializable>) field.getType());
        Object newValueForOriginal = examplesPair.getFirst();
        Object newValueForClone = examplesPair.getSecond();
        Object oldValueForOriginal = field.get(original);
        Object oldValueForClone = field.get(clone);
        // Ensure that the two objects really are equal before we tweak them
        boolean objectsTheSameBeforeTweak = original.equals(clone);
        if (!objectsTheSameBeforeTweak) {
          throw new TestCorrectnessException(
              "original was not equal to clone before tweaking them");
        }
        boolean objectsHashTheSameBeforeTweak = original.hashCode() == clone.hashCode();
        if (!objectsHashTheSameBeforeTweak) {
          throw new TestCorrectnessException(
              "original hash code was not equal to clone hash code before tweaking the objects");
        }
        field.set(original, newValueForOriginal);
        field.set(clone, newValueForClone);
        boolean equalsWorksAsIntended = !original.equals(clone);
        boolean hashWorksAsIntended = original.hashCode() != clone.hashCode();
        // Return to our original state before possibly failing
        field.set(original, oldValueForOriginal);
        field.set(clone, oldValueForClone);
        Assert.assertTrue(
            getFailureMessage(
                "equals", field, reachableClasses.getExamplePathTo(original.getClass())),
            equalsWorksAsIntended);
        Assert.assertTrue(
            getFailureMessage(
                "hash", field, reachableClasses.getExamplePathTo(original.getClass())),
            hashWorksAsIntended);
      }
    }
  }
}
