/*
 * Copyright 2018 Google LLC
 *
 * 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.auto.value;

import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;

import com.google.common.testing.EqualsTester;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.concurrent.ExecutionException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** @author emcmanus@google.com (Éamonn McManus) */
@RunWith(JUnit4.class)
public class AutoOneOfTest {
  @AutoValue
  public abstract static class Dog {
    public abstract String name();

    public static Dog create(String name) {
      return new AutoValue_AutoOneOfTest_Dog(name);
    }

    public void bark() {}
  }

  @AutoValue
  public abstract static class Cat {
    public static Cat create() {
      return new AutoValue_AutoOneOfTest_Cat();
    }

    public void meow() {}
  }

  @AutoValue
  public abstract static class TigerShark {
    public static TigerShark create() {
      return new AutoValue_AutoOneOfTest_TigerShark();
    }

    public void chomp() {}
  }

  @AutoOneOf(Pet.Kind.class)
  public abstract static class Pet {

    public static Pet create(Dog dog) {
      return AutoOneOf_AutoOneOfTest_Pet.dog(dog);
    }

    public static Pet create(Cat cat) {
      return AutoOneOf_AutoOneOfTest_Pet.cat(cat);
    }

    public static Pet create(TigerShark shark) {
      return AutoOneOf_AutoOneOfTest_Pet.tigerShark(shark);
    }

    public abstract Dog dog();

    public abstract Cat cat();

    public abstract TigerShark tigerShark();

    public enum Kind {
      DOG,
      CAT,
      TIGER_SHARK
    }

    public abstract Kind getKind();
  }

  @Test
  public void equality() {
    Dog marvin1 = Dog.create("Marvin");
    Pet petMarvin1 = Pet.create(marvin1);
    Dog marvin2 = Dog.create("Marvin");
    Pet petMarvin2 = Pet.create(marvin2);
    Dog isis = Dog.create("Isis");
    Pet petIsis = Pet.create(isis);
    Cat cat = Cat.create();
    new EqualsTester()
        .addEqualityGroup(marvin1, marvin2)
        .addEqualityGroup(petMarvin1, petMarvin2)
        .addEqualityGroup(petIsis)
        .addEqualityGroup(cat)
        .addEqualityGroup("foo")
        .testEquals();
  }

  @Test
  public void getCorrectType() {
    Dog marvin = Dog.create("Marvin");
    Pet petMarvin = Pet.create(marvin);
    assertThat(petMarvin.dog()).isSameInstanceAs(marvin);
  }

  @Test
  public void getWrongType() {
    Cat cat = Cat.create();
    Pet petCat = Pet.create(cat);
    try {
      petCat.tigerShark();
      fail();
    } catch (UnsupportedOperationException e) {
      assertThat(e).hasMessageThat().containsMatch("(?i:cat)");
    }
  }

  @Test
  public void string() {
    Dog marvin = Dog.create("Marvin");
    Pet petMarvin = Pet.create(marvin);
    assertThat(petMarvin.toString()).isEqualTo("Pet{dog=Dog{name=Marvin}}");
  }

  @Test
  public void getKind() {
    Dog marvin = Dog.create("Marvin");
    Pet petMarvin = Pet.create(marvin);
    Cat cat = Cat.create();
    Pet petCat = Pet.create(cat);
    TigerShark shark = TigerShark.create();
    Pet petShark = Pet.create(shark);
    assertThat(petMarvin.getKind()).isEqualTo(Pet.Kind.DOG);
    assertThat(petCat.getKind()).isEqualTo(Pet.Kind.CAT);
    assertThat(petShark.getKind()).isEqualTo(Pet.Kind.TIGER_SHARK);
  }

  @Test
  public void cannotBeNull() {
    try {
      Pet.create((Dog) null);
      fail();
    } catch (NullPointerException expected) {
    }
  }

  // Package-private case.

  @AutoOneOf(IntegerOrString.Kind.class)
  abstract static class IntegerOrString {
    enum Kind {
      INTEGER,
      STRING
    }

    abstract Kind getKind();

    abstract int integer();

    abstract String string();

    static IntegerOrString of(int x) {
      return AutoOneOf_AutoOneOfTest_IntegerOrString.integer(x);
    }

    static IntegerOrString of(String x) {
      return AutoOneOf_AutoOneOfTest_IntegerOrString.string(x);
    }
  }

  @Test
  public void packagePrivate() {
    IntegerOrString integer = IntegerOrString.of(23);
    IntegerOrString string = IntegerOrString.of("23");
    assertThat(integer.getKind()).isEqualTo(IntegerOrString.Kind.INTEGER);
    assertThat(string.getKind()).isEqualTo(IntegerOrString.Kind.STRING);
    assertThat(integer.integer()).isEqualTo(23);
    assertThat(string.string()).isEqualTo("23");
    assertThat(integer).isNotEqualTo(string);
    try {
      integer.string();
      fail();
    } catch (UnsupportedOperationException e) {
      assertThat(e).hasMessageThat().containsMatch("(?i:integer)");
    }
  }

  @AutoOneOf(Pet.Kind.class)
  public abstract static class PetWithGet {
    public abstract Dog getDog();

    public abstract Cat getCat();

    public abstract TigerShark getTigerShark();

    public static PetWithGet create(Dog dog) {
      return AutoOneOf_AutoOneOfTest_PetWithGet.dog(dog);
    }

    public static PetWithGet create(Cat cat) {
      return AutoOneOf_AutoOneOfTest_PetWithGet.cat(cat);
    }

    public static PetWithGet create(TigerShark shark) {
      return AutoOneOf_AutoOneOfTest_PetWithGet.tigerShark(shark);
    }

    public abstract Pet.Kind getKind();
  }

  @Test
  public void getPrefix() {
    Dog marvin = Dog.create("Marvin");
    PetWithGet petMarvin = PetWithGet.create(marvin);
    assertThat(petMarvin.toString()).isEqualTo("PetWithGet{dog=Dog{name=Marvin}}");
  }

  @AutoOneOf(Primitive.Kind.class)
  public abstract static class Primitive {
    public enum Kind {
      A_BYTE,
      A_SHORT,
      AN_INT,
      A_LONG,
      A_FLOAT,
      A_DOUBLE,
      A_CHAR,
      A_BOOLEAN
    }

    public abstract Kind getKind();

    public abstract byte aByte();

    public abstract short aShort();

    public abstract int anInt();

    public abstract long aLong();

    public abstract float aFloat();

    public abstract double aDouble();

    public abstract char aChar();

    public abstract boolean aBoolean();

    public static Primitive of(byte x) {
      return AutoOneOf_AutoOneOfTest_Primitive.aByte(x);
    }

    public static Primitive of(short x) {
      return AutoOneOf_AutoOneOfTest_Primitive.aShort(x);
    }

    public static Primitive of(int x) {
      return AutoOneOf_AutoOneOfTest_Primitive.anInt(x);
    }

    public static Primitive of(long x) {
      return AutoOneOf_AutoOneOfTest_Primitive.aLong(x);
    }

    public static Primitive of(float x) {
      return AutoOneOf_AutoOneOfTest_Primitive.aFloat(x);
    }

    public static Primitive of(double x) {
      return AutoOneOf_AutoOneOfTest_Primitive.aDouble(x);
    }

    public static Primitive of(char x) {
      return AutoOneOf_AutoOneOfTest_Primitive.aChar(x);
    }

    public static Primitive of(boolean x) {
      return AutoOneOf_AutoOneOfTest_Primitive.aBoolean(x);
    }
  }

  @Test
  public void primitive() {
    Primitive primitive = Primitive.of(17);
    assertThat(primitive.anInt()).isEqualTo(17);
    assertThat(primitive.toString()).isEqualTo("Primitive{anInt=17}");
  }

  @AutoOneOf(OneOfOne.Kind.class)
  public abstract static class OneOfOne {
    public enum Kind {
      DOG
    }

    public abstract Dog getDog();

    public static OneOfOne create(Dog dog) {
      return AutoOneOf_AutoOneOfTest_OneOfOne.dog(dog);
    }

    public abstract Kind getKind();
  }

  @Test
  public void oneOfOne() {
    Dog marvin = Dog.create("Marvin");
    OneOfOne oneOfMarvin = OneOfOne.create(marvin);
    assertThat(oneOfMarvin.toString()).isEqualTo("OneOfOne{dog=Dog{name=Marvin}}");
    assertThat(oneOfMarvin.getKind()).isEqualTo(OneOfOne.Kind.DOG);
  }

  // We allow this for consistency, even though it's obviously pretty useless.
  // The generated code might be rubbish, but it compiles. No concrete implementation is generated
  // so there isn't really anything to test beyond that it compiles.
  @AutoOneOf(OneOfNone.Kind.class)
  public abstract static class OneOfNone {
    public enum Kind {}

    public abstract Kind getKind();
  }

  // Testing generics. Typically generics will be a bit messy because the @AutoOneOf class must
  // have type parameters for every property that needs them, even though any given property
  // might not use all the type parameters.
  @AutoOneOf(TaskResult.Kind.class)
  public abstract static class TaskResult<V extends Serializable> {
    public enum Kind {
      VALUE,
      EXCEPTION
    }

    public abstract Kind getKind();

    public abstract V value();

    public abstract Throwable exception();

    public V get() throws ExecutionException {
      switch (getKind()) {
        case VALUE:
          return value();
        case EXCEPTION:
          throw new ExecutionException(exception());
      }
      throw new AssertionError(getKind());
    }

    static <V extends Serializable> TaskResult<V> value(V value) {
      return AutoOneOf_AutoOneOfTest_TaskResult.value(value);
    }

    static TaskResult<?> exception(Throwable exception) {
      return AutoOneOf_AutoOneOfTest_TaskResult.exception(exception);
    }
  }

  @Test
  public void taskResultValue() throws Exception {
    TaskResult<String> result = TaskResult.value("foo");
    assertThat(result.get()).isEqualTo("foo");
  }

  @Test
  public void taskResultException() {
    Exception exception = new IllegalArgumentException("oops");
    TaskResult<?> result = TaskResult.exception(exception);
    try {
      result.get();
      fail();
    } catch (ExecutionException e) {
      assertThat(e).hasCauseThat().isEqualTo(exception);
    }
  }

  @AutoOneOf(CustomToString.Kind.class)
  public abstract static class CustomToString {
    public enum Kind {
      ACE
    }

    public abstract Kind getKind();

    public abstract String ace();

    public static CustomToString ace(String ace) {
      return AutoOneOf_AutoOneOfTest_CustomToString.ace(ace);
    }

    @Override
    public String toString() {
      return "blim";
    }
  }

  // If you have an explicit toString() method, we won't override it.
  @Test
  public void customToString() {
    CustomToString x = CustomToString.ace("ceg");
    assertThat(x.toString()).isEqualTo("blim");
  }

  @AutoOneOf(AbstractToString.Kind.class)
  public abstract static class AbstractToString {
    public enum Kind {
      ACE
    }

    public abstract Kind getKind();

    public abstract String ace();

    public static AbstractToString ace(String ace) {
      return AutoOneOf_AutoOneOfTest_AbstractToString.ace(ace);
    }

    @Override
    public abstract String toString();
  }

  // If you have an explicit abstract toString() method, we will implement it.
  @Test
  public void abstractToString() {
    AbstractToString x = AbstractToString.ace("ceg");
    assertThat(x.toString()).isEqualTo("AbstractToString{ace=ceg}");
  }

  // "package" is a reserved word. You probably don't want to have a property with that name,
  // but if you insist, you can get one by using getFoo()-style methods. We leak our renaming
  // scheme here (package0) and for users that that bothers they can just avoid having properties
  // that are reserved words.
  @AutoOneOf(LetterOrPackage.Kind.class)
  public abstract static class LetterOrPackage {
    public enum Kind {
      LETTER,
      PACKAGE
    }

    public abstract Kind getKind();

    public abstract String getLetter();

    public abstract String getPackage();

    public static LetterOrPackage ofLetter(String letter) {
      return AutoOneOf_AutoOneOfTest_LetterOrPackage.letter(letter);
    }

    public static LetterOrPackage ofPackage(String pkg) {
      return AutoOneOf_AutoOneOfTest_LetterOrPackage.package0(pkg);
    }
  }

  @Test
  public void reservedWordProperty() {
    LetterOrPackage pkg = LetterOrPackage.ofPackage("pacquet");
    assertThat(pkg.toString()).isEqualTo("LetterOrPackage{package=pacquet}");
  }

  @AutoOneOf(ArrayValue.Kind.class)
  public abstract static class ArrayValue {
    public enum Kind {
      STRING,
      INTS
    }

    public abstract Kind getKind();

    public abstract String string();

    @SuppressWarnings("mutable")
    public abstract int[] ints();

    public static ArrayValue ofString(String string) {
      return AutoOneOf_AutoOneOfTest_ArrayValue.string(string);
    }

    public static ArrayValue ofInts(int[] ints) {
      return AutoOneOf_AutoOneOfTest_ArrayValue.ints(ints);
    }
  }

  @Test
  public void arrayValues() {
    ArrayValue string = ArrayValue.ofString("foo");
    ArrayValue ints1 = ArrayValue.ofInts(new int[] {17, 23});
    ArrayValue ints2 = ArrayValue.ofInts(new int[] {17, 23});
    new EqualsTester()
        .addEqualityGroup(string)
        .addEqualityGroup(ints1, ints2)
        .testEquals();
  }

  @Retention(RetentionPolicy.RUNTIME)
  public @interface CopyTest {
    int value();
  }

  @AutoOneOf(AnnotationNotCopied.Kind.class)
  @CopyTest(23)
  public abstract static class AnnotationNotCopied {
    public enum Kind {
      ACE
    }

    public abstract Kind getKind();

    public abstract String ace();

    public static AnnotationNotCopied ace(String ace) {
      return AutoOneOf_AutoOneOfTest_AnnotationNotCopied.ace(ace);
    }
  }

  @Test
  public void classAnnotationsNotCopiedByDefault() {
    assertThat(AnnotationNotCopied.class.isAnnotationPresent(CopyTest.class)).isTrue();
    AnnotationNotCopied ace = AnnotationNotCopied.ace("ace");
    assertThat(ace.getClass().isAnnotationPresent(CopyTest.class)).isFalse();
  }

  @AutoOneOf(AnnotationCopied.Kind.class)
  @CopyTest(23)
  @AutoValue.CopyAnnotations
  public abstract static class AnnotationCopied {
    public enum Kind {
      ACE
    }

    public abstract Kind getKind();

    public abstract String ace();

    public static AnnotationCopied ace(String ace) {
      return AutoOneOf_AutoOneOfTest_AnnotationCopied.ace(ace);
    }
  }

  @Test
  public void classAnnotationsCopiedIfCopyAnnotations() {
    assertThat(AnnotationCopied.class.isAnnotationPresent(CopyTest.class)).isTrue();
    AnnotationCopied ace = AnnotationCopied.ace("ace");
    assertThat(ace.getClass().isAnnotationPresent(CopyTest.class)).isTrue();
    assertThat(ace.getClass().getAnnotation(CopyTest.class).value()).isEqualTo(23);
  }

  @AutoOneOf(MaybeEmpty.Kind.class)
  public abstract static class MaybeEmpty implements Serializable {
    public enum Kind {
      EMPTY, STRING,
    }

    public abstract Kind getKind();

    public abstract void empty();

    public abstract String string();

    public static MaybeEmpty ofEmpty() {
      return AutoOneOf_AutoOneOfTest_MaybeEmpty.empty();
    }

    public static MaybeEmpty ofString(String s) {
      return AutoOneOf_AutoOneOfTest_MaybeEmpty.string(s);
    }
  }

  @Test
  public void voidPropertyIsSingleton() {
    MaybeEmpty empty1 = MaybeEmpty.ofEmpty();
    MaybeEmpty empty2 = MaybeEmpty.ofEmpty();
    assertThat(empty1).isSameInstanceAs(empty2);
  }

  @Test
  public void voidPropertyRemainsSingletonWhenDeserialized() throws Exception {
    MaybeEmpty empty1 = MaybeEmpty.ofEmpty();
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    // We're still compiling this with -source 6, so we can't use try-with-resources.
    ObjectOutputStream dos = new ObjectOutputStream(baos);
    dos.writeObject(empty1);
    dos.close();
    ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
    ObjectInputStream ois = new ObjectInputStream(bais);
    MaybeEmpty empty2 = (MaybeEmpty) ois.readObject();
    assertThat(empty2).isSameInstanceAs(empty1);
  }

  @Test
  public void voidPropertyToString() {
    MaybeEmpty empty = MaybeEmpty.ofEmpty();
    assertThat(empty.toString()).isEqualTo("MaybeEmpty{empty}");
  }

  @Test
  public void voidPropertyHashCodeIsIdentity() {
    MaybeEmpty empty = MaybeEmpty.ofEmpty();
    assertThat(empty.hashCode()).isEqualTo(System.identityHashCode(empty));
  }

  @Test
  public void voidPropertyGetterDoesNothing() {
    MaybeEmpty empty = MaybeEmpty.ofEmpty();
    empty.empty();
  }

  @Test
  public void voidPropertyNotEqualToNonVoid() {
    MaybeEmpty empty = MaybeEmpty.ofEmpty();
    MaybeEmpty notEmpty = MaybeEmpty.ofString("foo");
    assertThat(empty).isNotEqualTo(notEmpty);
    assertThat(notEmpty).isNotEqualTo(empty);
  }

  @Test
  public void voidPropertyWrongType() {
    MaybeEmpty notEmpty = MaybeEmpty.ofString("foo");
    try {
      notEmpty.empty();
      fail();
    } catch (UnsupportedOperationException e) {
      assertThat(e).hasMessageThat().containsMatch("(?i:string)");
    }
  }

  @AutoOneOf(OneOfArray.Kind.class)
  public abstract static class OneOfArray {
    public enum Kind {
      INTS
    }

    public abstract Kind getKind();

    @SuppressWarnings("mutable")
    public abstract int[] ints();

    public static OneOfArray ofInts(int[] s) {
      return AutoOneOf_AutoOneOfTest_OneOfArray.ints(s);
    }
  }

  @Test
  public void arrayToString() {
    OneOfArray oneOfArray = OneOfArray.ofInts(new int[] {1, 2});
    assertThat(oneOfArray.toString()).isEqualTo("OneOfArray{ints=[1, 2]}");
  }
}
