/*
 * Copyright 2014 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.common;

import java.util.List;
import java.util.Map;
import java.util.stream.StreamSupport;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.AnnotationValueVisitor;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementVisitor;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.TypeParameterElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.ArrayType;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.ErrorType;
import javax.lang.model.type.ExecutableType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVisitor;
import javax.lang.model.type.WildcardType;
import javax.lang.model.util.AbstractElementVisitor8;
import javax.lang.model.util.SimpleAnnotationValueVisitor8;
import javax.lang.model.util.SimpleTypeVisitor8;

/**
 * A utility class that traverses {@link Element} instances and ensures that all type information
 * is present and resolvable.
 *
 * @author Gregory Kick
 */
public final class SuperficialValidation {
  /**
   * Returns true if all of the given elements return true from {@link #validateElement(Element)}.
   */
  public static boolean validateElements(Iterable<? extends Element> elements) {
    return StreamSupport.stream(elements.spliterator(), false)
        .allMatch(SuperficialValidation::validateElement);
  }

  private static final ElementVisitor<Boolean, Void> ELEMENT_VALIDATING_VISITOR =
      new AbstractElementVisitor8<Boolean, Void>() {
        @Override
        public Boolean visitPackage(PackageElement e, Void p) {
          // don't validate enclosed elements because it will return types in the package
          return validateAnnotations(e.getAnnotationMirrors());
        }

        @Override
        public Boolean visitType(TypeElement e, Void p) {
          return isValidBaseElement(e)
              && validateElements(e.getTypeParameters())
              && validateTypes(e.getInterfaces())
              && validateType(e.getSuperclass());
        }

        @Override
        public Boolean visitVariable(VariableElement e, Void p) {
          return isValidBaseElement(e);
        }

        @Override
        public Boolean visitExecutable(ExecutableElement e, Void p) {
          AnnotationValue defaultValue = e.getDefaultValue();
          return isValidBaseElement(e)
              && (defaultValue == null || validateAnnotationValue(defaultValue, e.getReturnType()))
              && validateType(e.getReturnType())
              && validateTypes(e.getThrownTypes())
              && validateElements(e.getTypeParameters())
              && validateElements(e.getParameters());
        }

        @Override
        public Boolean visitTypeParameter(TypeParameterElement e, Void p) {
          return isValidBaseElement(e) && validateTypes(e.getBounds());
        }

        @Override
        public Boolean visitUnknown(Element e, Void p) {
          // just assume that unknown elements are OK
          return true;
        }
      };

  /**
   * Returns true if all types referenced by the given element are defined. The exact meaning of
   * this depends on the kind of element. For packages, it means that all annotations on the package
   * are fully defined. For other element kinds, it means that types referenced by the element,
   * anything it contains, and any of its annotations element are all defined.
   */
  public static boolean validateElement(Element element) {
    return element.accept(ELEMENT_VALIDATING_VISITOR, null);
  }

  private static boolean isValidBaseElement(Element e) {
    return validateType(e.asType())
        && validateAnnotations(e.getAnnotationMirrors())
        && validateElements(e.getEnclosedElements());
  }

  private static boolean validateTypes(Iterable<? extends TypeMirror> types) {
    for (TypeMirror type : types) {
      if (!validateType(type)) {
        return false;
      }
    }
    return true;
  }

  /*
   * This visitor does not test type variables specifically, but it seems that that is not actually
   * an issue.  Javac turns the whole type parameter into an error type if it can't figure out the
   * bounds.
   */
  private static final TypeVisitor<Boolean, Void> TYPE_VALIDATING_VISITOR =
      new SimpleTypeVisitor8<Boolean, Void>() {
        @Override
        protected Boolean defaultAction(TypeMirror t, Void p) {
          return true;
        }

        @Override
        public Boolean visitArray(ArrayType t, Void p) {
          return validateType(t.getComponentType());
        }

        @Override
        public Boolean visitDeclared(DeclaredType t, Void p) {
          return validateTypes(t.getTypeArguments());
        }

        @Override
        public Boolean visitError(ErrorType t, Void p) {
          return false;
        }

        @Override
        public Boolean visitUnknown(TypeMirror t, Void p) {
          // just make the default choice for unknown types
          return defaultAction(t, p);
        }

        @Override
        public Boolean visitWildcard(WildcardType t, Void p) {
          TypeMirror extendsBound = t.getExtendsBound();
          TypeMirror superBound = t.getSuperBound();
          return (extendsBound == null || validateType(extendsBound))
              && (superBound == null || validateType(superBound));
        }

        @Override
        public Boolean visitExecutable(ExecutableType t, Void p) {
          return validateTypes(t.getParameterTypes())
              && validateType(t.getReturnType())
              && validateTypes(t.getThrownTypes())
              && validateTypes(t.getTypeVariables());
        }
      };

  /**
   * Returns true if the given type is fully defined. This means that the type itself is defined, as
   * are any types it references, such as any type arguments or type bounds. For an {@link
   * ExecutableType}, the parameter and return types must be fully defined, as must types declared
   * in a {@code throws} clause or in the bounds of any type parameters.
   */
  public static boolean validateType(TypeMirror type) {
    return type.accept(TYPE_VALIDATING_VISITOR, null);
  }

  private static boolean validateAnnotations(
      Iterable<? extends AnnotationMirror> annotationMirrors) {
    for (AnnotationMirror annotationMirror : annotationMirrors) {
      if (!validateAnnotation(annotationMirror)) {
        return false;
      }
    }
    return true;
  }

  private static boolean validateAnnotation(AnnotationMirror annotationMirror) {
    return validateType(annotationMirror.getAnnotationType())
        && validateAnnotationValues(annotationMirror.getElementValues());
  }

  private static boolean validateAnnotationValues(
      Map<? extends ExecutableElement, ? extends AnnotationValue> valueMap) {
    return valueMap.entrySet().stream()
        .allMatch(
            valueEntry -> {
              TypeMirror expectedType = valueEntry.getKey().getReturnType();
              return validateAnnotationValue(valueEntry.getValue(), expectedType);
            });
  }

  private static final AnnotationValueVisitor<Boolean, TypeMirror> VALUE_VALIDATING_VISITOR =
      new SimpleAnnotationValueVisitor8<Boolean, TypeMirror>() {
        @Override
        protected Boolean defaultAction(Object o, TypeMirror expectedType) {
          return MoreTypes.isTypeOf(o.getClass(), expectedType);
        }

        @Override
        public Boolean visitUnknown(AnnotationValue av, TypeMirror expectedType) {
          // just take the default action for the unknown
          return defaultAction(av, expectedType);
        }

        @Override
        public Boolean visitAnnotation(AnnotationMirror a, TypeMirror expectedType) {
          return MoreTypes.equivalence().equivalent(a.getAnnotationType(), expectedType)
              && validateAnnotation(a);
        }

        @Override
        public Boolean visitArray(List<? extends AnnotationValue> values, TypeMirror expectedType) {
          if (!expectedType.getKind().equals(TypeKind.ARRAY)) {
            return false;
          }
          TypeMirror componentType = MoreTypes.asArray(expectedType).getComponentType();
          return values.stream().allMatch(value -> value.accept(this, componentType));
        }

        @Override
        public Boolean visitEnumConstant(VariableElement enumConstant, TypeMirror expectedType) {
          return MoreTypes.equivalence().equivalent(enumConstant.asType(), expectedType)
              && validateElement(enumConstant);
        }

        @Override
        public Boolean visitType(TypeMirror type, TypeMirror ignored) {
          // We could check assignability here, but would require a Types instance. Since this
          // isn't really the sort of thing that shows up in a bad AST from upstream compilation
          // we ignore the expected type and just validate the type.  It might be wrong, but
          // it's valid.
          return validateType(type);
        }

        @Override
        public Boolean visitBoolean(boolean b, TypeMirror expectedType) {
          return MoreTypes.isTypeOf(Boolean.TYPE, expectedType);
        }

        @Override
        public Boolean visitByte(byte b, TypeMirror expectedType) {
          return MoreTypes.isTypeOf(Byte.TYPE, expectedType);
        }

        @Override
        public Boolean visitChar(char c, TypeMirror expectedType) {
          return MoreTypes.isTypeOf(Character.TYPE, expectedType);
        }

        @Override
        public Boolean visitDouble(double d, TypeMirror expectedType) {
          return MoreTypes.isTypeOf(Double.TYPE, expectedType);
        }

        @Override
        public Boolean visitFloat(float f, TypeMirror expectedType) {
          return MoreTypes.isTypeOf(Float.TYPE, expectedType);
        }

        @Override
        public Boolean visitInt(int i, TypeMirror expectedType) {
          return MoreTypes.isTypeOf(Integer.TYPE, expectedType);
        }

        @Override
        public Boolean visitLong(long l, TypeMirror expectedType) {
          return MoreTypes.isTypeOf(Long.TYPE, expectedType);
        }

        @Override
        public Boolean visitShort(short s, TypeMirror expectedType) {
          return MoreTypes.isTypeOf(Short.TYPE, expectedType);
        }
      };

  private static boolean validateAnnotationValue(
      AnnotationValue annotationValue, TypeMirror expectedType) {
    return annotationValue.accept(VALUE_VALIDATING_VISITOR, expectedType);
  }

  private SuperficialValidation() {}
}
