package com.google.gerrit.entities.converter;

import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;

import com.google.common.collect.ImmutableList;
import com.google.common.primitives.Primitives;
import com.google.common.reflect.ClassPath;
import com.google.common.reflect.ClassPath.ClassInfo;
import com.google.common.testing.ArbitraryInstances;
import com.google.gerrit.common.ConvertibleToProto;
import com.google.gerrit.common.Nullable;
import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.Message;
import com.google.protobuf.MessageLite;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import javax.annotation.Nonnull;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class SafeProtoConverterTest {
  @Parameter(0)
  public SafeProtoConverter<Message, Object> converter;

  @Parameter(1)
  public String converterName;

  @Parameters(name = "{1}")
  public static ImmutableList<Object[]> listSafeConverters() throws Exception {
    return ClassPath.from(ClassLoader.getSystemClassLoader()).getAllClasses().stream()
        .filter(type -> type.getPackageName().contains("gerrit"))
        .map(ClassInfo::load)
        .filter(SafeProtoConverter.class::isAssignableFrom)
        .filter(clz -> !SafeProtoConverter.class.equals(clz))
        .filter(Class::isEnum)
        .map(clz -> (SafeProtoConverter<Message, Object>) clz.getEnumConstants()[0])
        .map(clz -> new Object[] {clz, clz.getClass().getSimpleName()})
        .collect(toImmutableList());
  }

  /**
   * For rising visibility, all Java Entity classes which have a {@link SafeProtoConverter}, must be
   * annotated with {@link ConvertibleToProto}.
   */
  @Test
  public void isJavaClassMarkedAsConvertibleToProto() {
    assertThat(converter.getEntityClass().getDeclaredAnnotation(ConvertibleToProto.class))
        .isNotNull();
  }

  /**
   * All {@link SafeProtoConverter} implementations must be enums with a single instance. Please
   * prefer descriptive enum and instance names, such as {@code MyTypeConverter::MY_TYPE_CONVERTER}.
   */
  @Test
  public void isConverterAValidEnum() {
    assertThat(converter.getClass().isEnum()).isTrue();
    assertThat(converter.getClass().getEnumConstants().length).isEqualTo(1);
  }

  /**
   * If this test fails, it's likely that you added a field to a Java class that has a {@link
   * SafeProtoConverter} set, or that you have changed the default value for such a field. Please
   * update the corresponding proto accordingly.
   */
  @Test
  public void javaDefaultsKeptOnDoubleConversion() {
    Object orig;
    try {
      orig = buildObjectWithFullFieldsOrThrow(converter.getEntityClass());
    } catch (Exception e) {
      throw new IllegalStateException(
          String.format(
              "Failed to build object for type %s, this likely means the buildObjectWithFullFieldsOrThrow should be adapted.",
              converter.getEntityClass().getName()),
          e);
    }
    Object res = converter.fromProto(converter.toProto(converter.getEntityClass().cast(orig)));
    assertThat(orig).isEqualTo(res);
    // If this assertion fails, it's likely that you forgot to update the `equals` method to include
    // your new field.
    assertThat(EqualsBuilder.reflectionEquals(orig, res)).isTrue();
  }

  /**
   * If this test fails, it's likely that you added a field to a proto that has a {@link
   * SafeProtoConverter} set, or that you have changed the default value for such a field. Please
   * update the corresponding Java class accordingly.
   */
  @Test
  public void protoDefaultsKeptOnDoubleConversion() {
    Message defaultInstance = getProtoDefaultInstance(converter.getProtoClass());
    Message preFilled = explicitlyFillProtoDefaults(defaultInstance);
    Message resFromDefault =
        converter.toProto(converter.fromProto(converter.getProtoClass().cast(preFilled)));
    Message resFromPrefilled =
        converter.toProto(converter.fromProto(converter.getProtoClass().cast(preFilled)));
    assertThat(resFromDefault).isEqualTo(preFilled);
    assertThat(resFromPrefilled).isEqualTo(preFilled);
  }

  @Nullable
  private static Object buildObjectWithFullFieldsOrThrow(Class<?> clz) throws Exception {
    if (clz == null) {
      return null;
    }
    Object obj = construct(clz);
    if (isSimple(clz)) {
      return obj;
    }
    for (Field field : clz.getDeclaredFields()) {
      if (Modifier.isStatic(field.getModifiers())) {
        continue;
      }
      Class<?> parameterizedType = getParameterizedType(field);
      if (!field.getType().isArray()
          && !Map.class.isAssignableFrom(field.getType())
          && !Collection.class.isAssignableFrom(field.getType())) {
        if (!field.trySetAccessible()) {
          return null;
        }
        field.set(obj, buildObjectWithFullFieldsOrThrow(field.getType()));
      } else if (Collection.class.isAssignableFrom(field.getType()) && parameterizedType != null) {
        field.set(obj, ImmutableList.of(buildObjectWithFullFieldsOrThrow(parameterizedType)));
      }
    }
    return obj;
  }

  /**
   * AutoValue annotations are not retained on runtime. We can only find out if a class is an
   * AutoValue, by trying to load the expected AutoValue class.
   *
   * <p>For the class {@code package.Clz}, the AutoValue class name is {@code
   * package.AutoValue_Clz}, for {@code package.Enclosing$Clz}, it is {@code
   * package.AutoValue_Enclosing_Clz}
   */
  static Optional<Class<?>> toRepresentingAutoValueClass(Class<?> clz) {
    String origClzName = clz.getName();
    String autoValueClzName =
        origClzName.substring(0, origClzName.lastIndexOf("."))
            + ".AutoValue_"
            + origClzName.substring(origClzName.lastIndexOf(".") + 1);
    autoValueClzName = autoValueClzName.replace('$', '_');
    try {
      return Optional.of(clz.getClassLoader().loadClass(autoValueClzName));
    } catch (Exception e) {
      return Optional.empty();
    }
  }

  @Nullable
  private static Class<?> getParameterizedType(Field field) {
    if (!Collection.class.isAssignableFrom(field.getType())) {
      return null;
    }
    Type genericType = field.getGenericType();
    if (genericType instanceof ParameterizedType) {
      return (Class<?>) ((ParameterizedType) genericType).getActualTypeArguments()[0];
    }
    return null;
  }

  @Nonnull
  static Object construct(@Nonnull Class<?> clz) {
    try {
      Object arbitrary = ArbitraryInstances.get(clz);
      if (arbitrary != null) {
        return arbitrary;
      }
      Optional<Class<?>> optionalAutoValueRepresentation = toRepresentingAutoValueClass(clz);
      if (optionalAutoValueRepresentation.isPresent()) {
        return construct(optionalAutoValueRepresentation.get());
      }
      Constructor<?> constructor =
          Arrays.stream(clz.getDeclaredConstructors())
              // Filter out copy constructors
              .filter(
                  c ->
                      c.getParameterCount() != 1 || !c.getParameterTypes()[0].isAssignableFrom(clz))
              // Filter out private constructors which cannot be set accessible.
              .filter(c -> c.canAccess(null) || c.trySetAccessible())
              .min(Comparator.comparingInt(Constructor::getParameterCount))
              .get();
      List<Object> args = new ArrayList<>();
      for (Class<?> f : constructor.getParameterTypes()) {
        args.add(construct(f));
      }
      return constructor.newInstance(args.toArray());
    } catch (Exception e) {
      throw new IllegalStateException("Failed to construct class " + clz.getName(), e);
    }
  }

  static boolean isSimple(Class<?> c) {
    return c.isPrimitive()
        || c.isEnum()
        || Primitives.isWrapperType(c)
        || String.class.isAssignableFrom(c)
        || Timestamp.class.isAssignableFrom(c);
  }

  /**
   * Returns the default instance for the given MessageLite class, if it has the {@code
   * getDefaultInstance} static method.
   *
   * @param type the protobuf message class
   * @throws IllegalArgumentException if the given class doesn't have the static {@code
   *     getDefaultInstance} method
   */
  public static <T extends MessageLite> T getProtoDefaultInstance(Class<T> type) {
    try {
      return type.cast(type.getMethod("getDefaultInstance").invoke(null));
    } catch (ReflectiveOperationException | ClassCastException e) {
      throw new IllegalStateException("Cannot get default instance for " + type, e);
    }
  }

  private static Message explicitlyFillProtoDefaults(Message defaultInstance) {
    Message.Builder res = defaultInstance.toBuilder();
    for (FieldDescriptor f : defaultInstance.getDescriptorForType().getFields()) {
      if (f.getType().equals(FieldDescriptor.Type.MESSAGE)) {
        res.setField(f, explicitlyFillProtoDefaults((Message) defaultInstance.getField(f)));
      } else {
        res.setField(f, defaultInstance.getField(f));
      }
    }
    return res.build();
  }
}
