package org.checkerframework.checker.units;

import java.lang.annotation.Annotation;
import java.util.Map;
import java.util.Set;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.util.Elements;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.checker.signature.qual.FullyQualifiedName;
import org.checkerframework.checker.units.qual.Prefix;
import org.checkerframework.checker.units.qual.UnknownUnits;
import org.checkerframework.framework.type.AnnotatedTypeMirror;
import org.checkerframework.javacutil.AnnotationBuilder;
import org.checkerframework.javacutil.AnnotationUtils;

/**
 * A helper class for UnitsRelations, providing numerous methods which help process Annotations and
 * Annotated Types representing various units.
 */
public class UnitsRelationsTools {

  /**
   * Creates an AnnotationMirror representing a unit defined by annoClass, with the specific Prefix
   * p.
   *
   * @param env the Checker Processing Environment, provided as a parameter in init() of a
   *     UnitsRelations implementation
   * @param annoClass the fully-qualified name of an Annotation representing a Unit (eg m.class for
   *     meters)
   * @param p a Prefix value
   * @return an AnnotationMirror of the Unit with the Prefix p, or null if it cannot be constructed
   */
  public static @Nullable AnnotationMirror buildAnnoMirrorWithSpecificPrefix(
      final ProcessingEnvironment env,
      final @FullyQualifiedName CharSequence annoClass,
      final Prefix p) {
    AnnotationBuilder builder = new AnnotationBuilder(env, annoClass);
    builder.setValue("value", p);
    return builder.build();
  }

  /**
   * Creates an AnnotationMirror representing a unit defined by annoClass, with no prefix.
   *
   * @param env checker Processing Environment, provided as a parameter in init() of a
   *     UnitsRelations implementation
   * @param annoClass the getElementValueClassname of an Annotation representing a Unit (eg m.class
   *     for meters)
   * @return an AnnotationMirror of the Unit with no prefix, or null if it cannot be constructed
   */
  public static @Nullable AnnotationMirror buildAnnoMirrorWithNoPrefix(
      final ProcessingEnvironment env, final @FullyQualifiedName CharSequence annoClass) {
    return AnnotationBuilder.fromName(env.getElementUtils(), annoClass);
  }

  /**
   * Retrieves the SI Prefix of an Annotated Type.
   *
   * @param annoType an AnnotatedTypeMirror representing a Units Annotated Type
   * @return a Prefix value (including Prefix.one), or null if it has none
   */
  public static @Nullable Prefix getPrefix(final AnnotatedTypeMirror annoType) {
    Prefix result = null;

    // go through each Annotation of an Annotated Type, find the prefix and return it
    for (AnnotationMirror mirror : annoType.getAnnotations()) {
      // try to get a prefix
      result = getPrefix(mirror);
      // if it is not null, then return the retrieved prefix immediately
      if (result != null) {
        return result;
      }
    }

    // if it can't find any prefix at all, then return null
    return result;
  }

  /**
   * Retrieves the SI Prefix of an Annotation.
   *
   * @param unitsAnnotation an AnnotationMirror representing a Units Annotation
   * @return a Prefix value (including Prefix.one), or null if it has none
   */
  public static @Nullable Prefix getPrefix(final AnnotationMirror unitsAnnotation) {
    AnnotationValue annotationValue = getAnnotationMirrorPrefix(unitsAnnotation);

    // if this Annotation has no prefix, return null
    if (hasNoPrefix(annotationValue)) {
      return null;
    }

    // if the Annotation has a value, then detect and match the string name of the prefix, and
    // return the matching Prefix
    String prefixString = annotationValue.getValue().toString();
    for (Prefix prefix : Prefix.values()) {
      if (prefixString.equals(prefix.toString())) {
        return prefix;
      }
    }

    // if none of the strings match, then return null
    return null;
  }

  /**
   * Checks to see if an Annotated Type has no prefix.
   *
   * @param annoType an AnnotatedTypeMirror representing a Units Annotated Type
   * @return true if it has no prefix, false otherwise
   */
  public static boolean hasNoPrefix(final AnnotatedTypeMirror annoType) {
    for (AnnotationMirror mirror : annoType.getAnnotations()) {
      // if any Annotation has a prefix, return false
      if (!hasNoPrefix(mirror)) {
        return false;
      }
    }

    return true;
  }

  /**
   * Checks to see if an Annotation has no prefix (ie, no value element).
   *
   * @param unitsAnnotation an AnnotationMirror representing a Units Annotation
   * @return true if it has no prefix, false otherwise
   */
  public static boolean hasNoPrefix(final AnnotationMirror unitsAnnotation) {
    AnnotationValue annotationValue = getAnnotationMirrorPrefix(unitsAnnotation);
    return hasNoPrefix(annotationValue);
  }

  private static boolean hasNoPrefix(final AnnotationValue annotationValue) {
    // Annotation has no element value (ie no SI prefix)
    if (annotationValue == null) {
      return true;
    } else {
      return false;
    }
  }

  /**
   * Given an Annotation, returns the prefix (eg kilo) as an AnnotationValue if there is any,
   * otherwise returns null.
   */
  private static @Nullable AnnotationValue getAnnotationMirrorPrefix(
      final AnnotationMirror unitsAnnotation) {
    Map<? extends ExecutableElement, ? extends AnnotationValue> elementValues =
        unitsAnnotation.getElementValues();

    for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry :
        elementValues.entrySet()) {
      if (entry.getKey().getSimpleName().contentEquals("value")) {
        return entry.getValue();
      }
    }

    return null;
  }

  /**
   * Removes the prefix value from an Annotation, by constructing and returning a copy of its base
   * SI unit's Annotation.
   *
   * @param elements the Element Utilities from a checker's processing environment, typically
   *     obtained by calling env.getElementUtils() in init() of a Units Relations implementation
   * @param unitsAnnotation an AnnotationMirror representing a Units Annotation
   * @return the base SI Unit's AnnotationMirror, or null if the base SI Unit cannot be constructed
   */
  public static @Nullable AnnotationMirror removePrefix(
      final Elements elements, final AnnotationMirror unitsAnnotation) {
    if (hasNoPrefix(unitsAnnotation)) {
      // Optimization, though the else case would also work.
      return unitsAnnotation;
    } else {
      String unitsAnnoName = AnnotationUtils.annotationName(unitsAnnotation);
      // In the Units Checker, the only annotation value is the prefix value.  Therefore,
      // fromName (which creates an annotation with no values) is acceptable.
      // TODO: refine sensitivity of removal for extension units, in case extension
      // Annotations have more than just Prefix in its values.
      return AnnotationBuilder.fromName(elements, unitsAnnoName);
    }
  }

  /**
   * Removes the Prefix value from an Annotated Type, by constructing and returning a copy of the
   * Annotated Type without the prefix.
   *
   * @param elements the Element Utilities from a checker's processing environment, typically
   *     obtained by calling env.getElementUtils() in init() of a Units Relations implementation
   * @param annoType an AnnotatedTypeMirror representing a Units Annotated Type
   * @return a copy of the Annotated Type without the prefix
   */
  public static AnnotatedTypeMirror removePrefix(
      final Elements elements, final AnnotatedTypeMirror annoType) {
    // deep copy the Annotated Type Mirror without any of the Annotations
    AnnotatedTypeMirror result = annoType.deepCopy(false);

    // get all of the original Annotations in the Annotated Type
    Set<AnnotationMirror> annos = annoType.getAnnotations();

    // loop through all the Annotations to see if they use Prefix.one, remove Prefix.one if it does
    for (AnnotationMirror anno : annos) {
      // try to clean the Annotation Mirror of the Prefix
      AnnotationMirror cleanedMirror = removePrefix(elements, anno);
      // if successful, add the cleaned annotation to the deep copy
      if (cleanedMirror != null) {
        result.addAnnotation(cleanedMirror);
      }
      // if unsuccessful, add the original annotation
      else {
        result.addAnnotation(anno);
      }
    }

    return result;
  }

  /**
   * Checks to see if a particular Annotated Type has no units, such as scalar constants in
   * calculations.
   *
   * <p>Any number that isn't assigned a unit will automatically get the Annotation UnknownUnits.
   * eg: int x = 5; // x has @UnknownUnits
   *
   * @param annoType an AnnotatedTypeMirror representing a Units Annotated Type
   * @return true if the Type has no units, false otherwise
   */
  public static boolean hasNoUnits(final AnnotatedTypeMirror annoType) {
    return (annoType.getAnnotation(UnknownUnits.class) != null);
  }

  /**
   * Checks to see if a particular Annotated Type has a specific unit (represented by its
   * Annotation).
   *
   * @param annoType an AnnotatedTypeMirror representing a Units Annotated Type
   * @param unitsAnnotation an AnnotationMirror representing a Units Annotation of a specific unit
   * @return true if the Type has the specific unit, false otherwise
   */
  public static boolean hasSpecificUnit(
      final AnnotatedTypeMirror annoType, final AnnotationMirror unitsAnnotation) {
    return AnnotationUtils.containsSame(annoType.getAnnotations(), unitsAnnotation);
  }

  /**
   * Checks to see if a particular Annotated Type has a particular base unit (represented by its
   * Annotation).
   *
   * @param annoType an AnnotatedTypeMirror representing a Units Annotated Type
   * @param unitsAnnotation an AnnotationMirror representing a Units Annotation of the base unit
   * @return true if the Type has the specific unit, false otherwise
   */
  public static boolean hasSpecificUnitIgnoringPrefix(
      final AnnotatedTypeMirror annoType, final AnnotationMirror unitsAnnotation) {
    return AnnotationUtils.containsSameByName(annoType.getAnnotations(), unitsAnnotation);
  }

  /**
   * Creates an AnnotationMirror representing a unit defined by annoClass, with the specific Prefix
   * p.
   *
   * <p>This interface is intended only for subclasses of UnitsRelations; other clients should use
   * {@link #buildAnnoMirrorWithSpecificPrefix(ProcessingEnvironment, CharSequence, Prefix)}
   *
   * @param env the Checker Processing Environment, provided as a parameter in init() of a
   *     UnitsRelations implementation
   * @param annoClass the Class of an Annotation representing a Unit (eg m.class for meters)
   * @param p a Prefix value
   * @return an AnnotationMirror of the Unit with the Prefix p, or null if it cannot be constructed
   */
  public static @Nullable AnnotationMirror buildAnnoMirrorWithSpecificPrefix(
      final ProcessingEnvironment env,
      final Class<? extends Annotation> annoClass,
      final Prefix p) {
    AnnotationBuilder builder = new AnnotationBuilder(env, annoClass);
    builder.setValue("value", p);
    return builder.build();
  }

  /**
   * Creates an AnnotationMirror representing a unit defined by annoClass, with the default Prefix
   * of {@code Prefix.one}.
   *
   * <p>This interface is intended only for subclasses of UnitsRelations; other clients should not
   * use it.
   *
   * @param env the Checker Processing Environment, provided as a parameter in init() of a
   *     UnitsRelations implementation
   * @param annoClass the Class of an Annotation representing a Unit (eg m.class for meters)
   * @return an AnnotationMirror of the Unit with Prefix.one, or null if it cannot be constructed
   */
  public static @Nullable AnnotationMirror buildAnnoMirrorWithDefaultPrefix(
      final ProcessingEnvironment env, final Class<? extends Annotation> annoClass) {
    return buildAnnoMirrorWithSpecificPrefix(env, annoClass, Prefix.one);
  }

  /**
   * Creates an AnnotationMirror representing a unit defined by annoClass, with no prefix.
   *
   * <p>This interface is intended only for subclasses of UnitsRelations; other clients should use
   * {@link #buildAnnoMirrorWithNoPrefix(ProcessingEnvironment, CharSequence)}.
   *
   * @param env checker Processing Environment, provided as a parameter in init() of a
   *     UnitsRelations implementation
   * @param annoClass the Class of an Annotation representing a Unit (eg m.class for meters)
   * @return an AnnotationMirror of the Unit with no prefix, or null if it cannot be constructed
   */
  static @Nullable AnnotationMirror buildAnnoMirrorWithNoPrefix(
      final ProcessingEnvironment env, final Class<? extends Annotation> annoClass) {
    return AnnotationBuilder.fromClass(env.getElementUtils(), annoClass);
  }
}
