/*
 * 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;

import com.google.common.base.Objects;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.idea.blaze.base.model.blaze.deepequalstester.DeepEqualsTester;
import com.google.idea.blaze.base.model.blaze.deepequalstester.DeepEqualsTester.TestCorrectnessException;
import com.google.idea.blaze.base.model.blaze.deepequalstester.DeepEqualsTesterUtil;
import com.google.idea.blaze.base.model.blaze.deepequalstester.Examples;
import com.google.idea.blaze.base.model.blaze.deepequalstester.Examples.ExampleNotFoundException;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;

import java.io.File;
import java.io.Serializable;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * Tests to verify that our equals tester is working correctly
 */
public class DeepEqualsTesterTest {

  // The equals method does not work correctly if T is an array
  private static class Box<T> implements Serializable {

    public T data;

    public Box(T data) {
      this.data = data;
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) {
        return true;
      }
      if (o == null || getClass() != o.getClass()) {
        return false;
      }
      Box<?> box = (Box<?>)o;
      return Objects.equal(data, box.data);
    }

    @Override
    public int hashCode() {
      return Objects.hashCode(data);
    }
  }

  private static class CorrectEqualsAndHash implements Serializable {

    public String name;

    public CorrectEqualsAndHash(String name) {
      this.name = name;
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) {
        return true;
      }
      if (o == null || getClass() != o.getClass()) {
        return false;
      }
      CorrectEqualsAndHash foo = (CorrectEqualsAndHash)o;
      return Objects.equal(name, foo.name);
    }

    @Override
    public int hashCode() {
      return Objects.hashCode(name);
    }
  }

  private static class ClassWithCorrectEqualsMember implements Serializable {

    public String myName;
    public CorrectEqualsAndHash myCorrectEqualsAndHash;

    public ClassWithCorrectEqualsMember(String name, String innerName) {
      this.myName = name;
      this.myCorrectEqualsAndHash = new CorrectEqualsAndHash(innerName);
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) {
        return true;
      }
      if (o == null || getClass() != o.getClass()) {
        return false;
      }
      ClassWithCorrectEqualsMember that = (ClassWithCorrectEqualsMember)o;
      return Objects.equal(myName, that.myName) &&
             Objects.equal(myCorrectEqualsAndHash, that.myCorrectEqualsAndHash);
    }

    @Override
    public int hashCode() {
      return Objects.hashCode(myName, myCorrectEqualsAndHash);
    }
  }

  private static class IncorrectHash implements Serializable {

    public String name;
    public int num;

    public IncorrectHash(String name, int num) {
      this.name = name;
      this.num = num;
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) {
        return true;
      }
      if (o == null || getClass() != o.getClass()) {
        return false;
      }
      IncorrectHash foo = (IncorrectHash)o;
      return Objects.equal(name, foo.name) && Objects.equal(num, foo.num);
    }

    @Override
    public int hashCode() {
      return Objects.hashCode(name);
    }
  }

  private static class IncorrectEqualsAndHash implements Serializable {

    public String name;
    public int num;

    public IncorrectEqualsAndHash(String name, int num) {
      this.name = name;
      this.num = num;
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) {
        return true;
      }
      if (o == null || getClass() != o.getClass()) {
        return false;
      }
      IncorrectEqualsAndHash foo = (IncorrectEqualsAndHash)o;
      return Objects.equal(name, foo.name);
    }

    @Override
    public int hashCode() {
      return Objects.hashCode(name);
    }
  }

  private static class ClassWithIncorrectEqualsMember implements Serializable {

    public String myName;
    public IncorrectEqualsAndHash myIncorrectEqualsAndHash;

    public ClassWithIncorrectEqualsMember(String name, String innerName, int innerNum) {
      this.myName = name;
      this.myIncorrectEqualsAndHash = new IncorrectEqualsAndHash(innerName, innerNum);
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) {
        return true;
      }
      if (o == null || getClass() != o.getClass()) {
        return false;
      }
      ClassWithIncorrectEqualsMember that = (ClassWithIncorrectEqualsMember)o;
      return Objects.equal(myName, that.myName) &&
             Objects.equal(myIncorrectEqualsAndHash, that.myIncorrectEqualsAndHash);
    }

    @Override
    public int hashCode() {
      return Objects.hashCode(myName, myIncorrectEqualsAndHash);
    }
  }

  private static class IncorrectEqualsWithArray implements Serializable {

    public IncorrectEqualsAndHash[] array;

    public IncorrectEqualsWithArray(IncorrectEqualsAndHash[] array) {
      this.array = array;
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) {
        return true;
      }
      if (o == null || getClass() != o.getClass()) {
        return false;
      }
      IncorrectEqualsWithArray that = (IncorrectEqualsWithArray)o;
      return Arrays.equals(array, that.array);
    }

    @Override
    public int hashCode() {
      return Objects.hashCode((Object[])array);
    }
  }

  private static class SubIncorrectEqualsAndHash extends IncorrectEqualsAndHash {

    public Long num;

    public SubIncorrectEqualsAndHash(String name, int iNum, Long num) {
      super(name, iNum);
      this.num = num;
    }
  }

  private static enum ENUMS {
    ONE, TWO, THREE
  }

  private static class DeepClass<T> implements Serializable {

    public ENUMS myEnum;
    public char myC;
    public T data;
    public File f;

    public DeepClass(ENUMS myEnum, char c, T data, File f) {
      this.myEnum = myEnum;
      this.myC = c;
      this.data = data;
      this.f = f;
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) {
        return true;
      }
      if (o == null || getClass() != o.getClass()) {
        return false;
      }
      DeepClass<?> deepClass = (DeepClass<?>)o;
      return Objects.equal(myC, deepClass.myC) &&
             Objects.equal(myEnum, deepClass.myEnum) &&
             Objects.equal(data, deepClass.data) &&
             Objects.equal(f, deepClass.f);
    }

    @Override
    public int hashCode() {
      return Objects.hashCode(myEnum, myC, data, f);
    }
  }

  private static class SimpleClassWithSet implements Serializable {

    public Set<File> files;

    public SimpleClassWithSet(Set<File> files) {
      this.files = files;
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) {
        return true;
      }
      if (o == null || getClass() != o.getClass()) {
        return false;
      }
      SimpleClassWithSet that = (SimpleClassWithSet)o;
      return Objects.equal(files, that.files);
    }

    @Override
    public int hashCode() {
      return Objects.hashCode(files);
    }
  }

  private static class MapWithIncorrectKey implements Serializable {

    public Map<IncorrectEqualsAndHash, File> files;

    public MapWithIncorrectKey(Map<IncorrectEqualsAndHash, File> files) {
      this.files = files;
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) {
        return true;
      }
      if (o == null || getClass() != o.getClass()) {
        return false;
      }
      MapWithIncorrectKey that = (MapWithIncorrectKey)o;
      return Objects.equal(files, that.files);
    }

    @Override
    public int hashCode() {
      return Objects.hashCode(files);
    }
  }

  private static class MapWithIncorrectValue implements Serializable {

    public Map<String, IncorrectEqualsAndHash> map;

    public MapWithIncorrectValue(Map<String, IncorrectEqualsAndHash> map) {
      this.map = map;
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) {
        return true;
      }
      if (o == null || getClass() != o.getClass()) {
        return false;
      }
      MapWithIncorrectValue that = (MapWithIncorrectValue)o;
      return Objects.equal(map, that.map);
    }

    @Override
    public int hashCode() {
      return Objects.hashCode(map);
    }
  }

  private static class MapWithCorrectKeyAndValues implements Serializable {

    public Map<String, String> map;

    public MapWithCorrectKeyAndValues(Map<String, String> map) {
      this.map = map;
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) {
        return true;
      }
      if (o == null || getClass() != o.getClass()) {
        return false;
      }
      MapWithCorrectKeyAndValues that = (MapWithCorrectKeyAndValues)o;
      return Objects.equal(map, that.map);
    }

    @Override
    public int hashCode() {
      return Objects.hashCode(map);
    }
  }

  private Examples testExamples;

  @Before
  public void populateExtraExamples() {
    testExamples = new Examples();
    testExamples.addExample(CorrectEqualsAndHash.class, new CorrectEqualsAndHash("A"),
                            new CorrectEqualsAndHash("B"));
    testExamples.addExample(IncorrectEqualsAndHash.class, new IncorrectEqualsAndHash("A", 100),
                            new IncorrectEqualsAndHash("A", 200));
    testExamples
      .addExample(IncorrectHash.class, new IncorrectHash("A", 100), new IncorrectHash("A", 200));
  }

  @Test
  public void testCorrectEqualsAndHashPassesTester()
    throws IllegalAccessException, InstantiationException, NoSuchFieldException, ExampleNotFoundException, TestCorrectnessException {
    CorrectEqualsAndHash myFoo = new CorrectEqualsAndHash("test");
    DeepEqualsTester.doDeepEqualsAndHashTest(myFoo, testExamples);
  }

  @Test(expected = AssertionError.class)
  public void testIncorrectEqualsFailsTester()
    throws IllegalAccessException, InstantiationException, NoSuchFieldException, ExampleNotFoundException, TestCorrectnessException {
    IncorrectEqualsAndHash myFoo = new IncorrectEqualsAndHash("test", 4);
    DeepEqualsTester.doDeepEqualsAndHashTest(myFoo, testExamples);
  }

  @Test(expected = AssertionError.class)
  public void testIncorrectHashFailsTester()
    throws IllegalAccessException, InstantiationException, NoSuchFieldException, ExampleNotFoundException, TestCorrectnessException {
    IncorrectHash myFoo = new IncorrectHash("test", 4);
    DeepEqualsTester.doDeepEqualsAndHashTest(myFoo, testExamples);
  }

  @Test
  public void testCorrectDeepEqualsAndHashPassesTester()
    throws IllegalAccessException, InstantiationException, NoSuchFieldException, ExampleNotFoundException, TestCorrectnessException {
    ClassWithCorrectEqualsMember myFoo = new ClassWithCorrectEqualsMember("test", "inner test");
    DeepEqualsTester.doDeepEqualsAndHashTest(myFoo, testExamples);
  }

  @Test(expected = AssertionError.class)
  public void testDeepIncorrectEqualsFailsTester()
    throws IllegalAccessException, InstantiationException, NoSuchFieldException, ExampleNotFoundException, TestCorrectnessException {
    ClassWithIncorrectEqualsMember myFoo = new ClassWithIncorrectEqualsMember("test", "inner test",
                                                                              4);
    DeepEqualsTester.doDeepEqualsAndHashTest(myFoo, testExamples);
  }

  @Test(expected = AssertionError.class)
  public void testIncorrectEqualsInSuperclassFailsTester()
    throws IllegalAccessException, InstantiationException, NoSuchFieldException, ExampleNotFoundException, TestCorrectnessException {
    SubIncorrectEqualsAndHash myFoo = new SubIncorrectEqualsAndHash("test", 4, new Long(39903));
    DeepEqualsTester.doDeepEqualsAndHashTest(myFoo, testExamples);
  }

  @Test
  public void testCorrectEqualsAndHashInArrayPassesTester()
    throws IllegalAccessException, InstantiationException, NoSuchFieldException, ExampleNotFoundException, TestCorrectnessException {
    CorrectEqualsAndHash myFoo = new CorrectEqualsAndHash("test");
    CorrectEqualsAndHash[] array = new CorrectEqualsAndHash[1];
    array[0] = myFoo;
    DeepEqualsTester.doDeepEqualsAndHashTest(array, testExamples);
  }

  @Test(expected = AssertionError.class)
  public void testIncorrectEqualsInArrayFailsTester()
    throws IllegalAccessException, InstantiationException, NoSuchFieldException, ExampleNotFoundException, TestCorrectnessException {
    IncorrectEqualsAndHash myFoo = new IncorrectEqualsAndHash("test", 4);
    IncorrectEqualsAndHash[] array = new IncorrectEqualsAndHash[1];
    array[0] = myFoo;
    IncorrectEqualsWithArray toTest = new IncorrectEqualsWithArray(array);
    DeepEqualsTester.doDeepEqualsAndHashTest(toTest, testExamples);
  }

  @Test
  public void testClassWithSetWithCorrectDeepEqualsAndHashPassesTester()
    throws IllegalAccessException, InstantiationException, NoSuchFieldException, ExampleNotFoundException, TestCorrectnessException {
    Set<File> myFiles = Sets.newHashSet();
    myFiles.add(new File("foo"));
    myFiles.add(new File("bar"));
    SimpleClassWithSet myFoo = new SimpleClassWithSet(myFiles);
    DeepEqualsTester.doDeepEqualsAndHashTest(myFoo, testExamples);
  }

  @Ignore("causes java reflection return a type variable instead of a concrete type")
  @Test
  public void testCorrectEqualsAndHashInSetPassesTester()
    throws IllegalAccessException, InstantiationException, NoSuchFieldException, ExampleNotFoundException, TestCorrectnessException {
    CorrectEqualsAndHash myFoo = new CorrectEqualsAndHash("test");
    HashSet<CorrectEqualsAndHash> set = Sets.newHashSet();
    set.add(myFoo);
    DeepEqualsTester.doDeepEqualsAndHashTest(new Box<HashSet<CorrectEqualsAndHash>>(set),
                                             testExamples);
  }

  @Test(expected = AssertionError.class)
  public void testIncorrectEqualsInSetFailsTester()
    throws IllegalAccessException, InstantiationException, NoSuchFieldException, ExampleNotFoundException, TestCorrectnessException {
    IncorrectEqualsAndHash myFoo = new IncorrectEqualsAndHash("test", 4);
    HashSet<IncorrectEqualsAndHash> set = Sets.newHashSet();
    set.add(myFoo);
    DeepEqualsTester.doDeepEqualsAndHashTest(new Box<HashSet<IncorrectEqualsAndHash>>(set),
                                             testExamples);
  }

  @Ignore("causes java reflection return a type variable instead of a concrete type")
  @Test
  public void testCorrectDeepEqualsAndHashInSetPassesTester()
    throws IllegalAccessException, InstantiationException, NoSuchFieldException, ExampleNotFoundException, TestCorrectnessException {
    CorrectEqualsAndHash myFoo = new CorrectEqualsAndHash("test");
    DeepClass<CorrectEqualsAndHash> data = new DeepClass<CorrectEqualsAndHash>(ENUMS.THREE, 'z',
                                                                               myFoo,
                                                                               new File("home"));
    HashSet<DeepClass<CorrectEqualsAndHash>> set = Sets.newHashSet();
    set.add(data);
    DeepEqualsTester
      .doDeepEqualsAndHashTest(new Box<HashSet<DeepClass<CorrectEqualsAndHash>>>(set),
                               testExamples);
  }

  @Test(expected = AssertionError.class)
  public void testIncorrectDeepEqualsInSetFailsTester()
    throws IllegalAccessException, InstantiationException, NoSuchFieldException, ExampleNotFoundException, TestCorrectnessException {
    IncorrectEqualsAndHash myFoo = new IncorrectEqualsAndHash("test", 4);
    DeepClass<IncorrectEqualsAndHash> data = new DeepClass<IncorrectEqualsAndHash>(ENUMS.ONE, 'e',
                                                                                   myFoo,
                                                                                   new File("home"));
    HashSet<DeepClass<IncorrectEqualsAndHash>> set = Sets.newHashSet();
    set.add(data);
    DeepEqualsTester
      .doDeepEqualsAndHashTest(new Box<HashSet<DeepClass<IncorrectEqualsAndHash>>>(set),
                               testExamples);
  }

  @Test(expected = AssertionError.class)
  public void testIncorrectEqualsForMapKeyFailsTester()
    throws IllegalAccessException, InstantiationException, NoSuchFieldException, ExampleNotFoundException, TestCorrectnessException {
    IncorrectEqualsAndHash myFoo = new IncorrectEqualsAndHash("test", 4);
    Map<IncorrectEqualsAndHash, File> map = Maps.newHashMap();
    map.put(myFoo, new File("file"));
    MapWithIncorrectKey data = new MapWithIncorrectKey(map);
    DeepEqualsTester.doDeepEqualsAndHashTest(data, testExamples);
  }

  @Test(expected = AssertionError.class)
  public void testIncorrectEqualsForMapValueFailsTester()
    throws IllegalAccessException, InstantiationException, NoSuchFieldException, ExampleNotFoundException, TestCorrectnessException {
    IncorrectEqualsAndHash myFoo = new IncorrectEqualsAndHash("test", 4);
    Map<String, IncorrectEqualsAndHash> map = Maps.newHashMap();
    map.put("first", myFoo);
    MapWithIncorrectValue data = new MapWithIncorrectValue(map);
    DeepEqualsTester.doDeepEqualsAndHashTest(data, testExamples);
  }

  @Test
  public void testCorrectEqualsAndHashForMapKeyValuePassesTester()
    throws IllegalAccessException, InstantiationException, NoSuchFieldException, ExampleNotFoundException, TestCorrectnessException {
    Map<String, String> map = Maps.newHashMap();
    map.put("key", "value");
    MapWithCorrectKeyAndValues data = new MapWithCorrectKeyAndValues(map);
    DeepEqualsTester.doDeepEqualsAndHashTest(data, testExamples);
  }

  @Test
  public void testEqualsAfterCloneReturnsTrue() {
    CorrectEqualsAndHash myData = new CorrectEqualsAndHash("my data");
    CorrectEqualsAndHash clone = (CorrectEqualsAndHash)DeepEqualsTesterUtil
      .cloneWithSerialization(myData);
    Assert.assertEquals(myData, clone);
  }
}
