package org.checkerframework.framework.util.typeinference.solver;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.type.TypeVariable;
import org.checkerframework.framework.type.AnnotatedTypeMirror;
import org.checkerframework.framework.type.QualifierHierarchy;
import org.checkerframework.framework.util.AnnotationMirrorSet;
import org.checkerframework.framework.util.typeinference.solver.TargetConstraints.Equalities;
import org.checkerframework.framework.util.typeinference.solver.TargetConstraints.Subtypes;
import org.checkerframework.framework.util.typeinference.solver.TargetConstraints.Supertypes;

/**
 * ConstraintMap holds simplified versions of the TUConstraints for ALL type variable for which we
 * are inferring an argument. The ConstraintMap is edited on the fly as the various solvers work
 * (unlike the AF/TU Constraints which are immutable).
 *
 * <p>This really consists of these things:
 *
 * <ol>
 *   <li>a Map({@code target => constraints for target})
 *   <li>Methods to easily build up the constraints in the map
 *   <li>A getter for the constraints of individual targets.
 * </ol>
 *
 * Note: This class, along with TargetConstraints, uses a lot of mutable state and few
 * setters/getters be careful. This choice was made as it makes the resulting code more readable.
 */
public class ConstraintMap {

  private final Map<TypeVariable, TargetConstraints> targetToRecords = new LinkedHashMap<>();

  public ConstraintMap(Set<TypeVariable> targets) {
    for (final TypeVariable target : targets) {
      targetToRecords.put(target, new TargetConstraints(target));
    }
  }

  public ConstraintMap(final ConstraintMap toCopy) {
    this.targetToRecords.putAll(toCopy.targetToRecords);
  }

  /** Gets the equality, subtypes, and supertypes constraints for a particular target. */
  public TargetConstraints getConstraints(final TypeVariable target) {
    return targetToRecords.get(target);
  }

  /**
   * Returns the set of all targets passed to the constructor of this constraint map (a target will
   * appear in this list whether or not it has any constraints added).
   *
   * @return the set of all targets passed to the constructor of this constraint map (a target will
   *     appear in this list whether or not it has any constraints added)
   */
  public Set<TypeVariable> getTargets() {
    return targetToRecords.keySet();
  }

  /**
   * Add a constraint indicating that the equivalent is equal to target in the given qualifier
   * hierarchies.
   */
  public void addTargetEquality(
      final TypeVariable target, final TypeVariable equivalent, AnnotationMirrorSet hierarchies) {
    final Equalities equalities = targetToRecords.get(target).equalities;
    final AnnotationMirrorSet equivalentTops =
        equalities.targets.computeIfAbsent(equivalent, __ -> new AnnotationMirrorSet());
    equivalentTops.addAll(hierarchies);
  }

  /**
   * Add a constraint indicating that target has primary annotations equal to the given annotations.
   */
  public void addPrimaryEqualities(
      final TypeVariable target,
      QualifierHierarchy qualHierarchy,
      final AnnotationMirrorSet annos) {
    final Equalities equalities = targetToRecords.get(target).equalities;

    for (final AnnotationMirror anno : annos) {
      final AnnotationMirror top = qualHierarchy.getTopAnnotation(anno);
      if (!equalities.primaries.containsKey(top)) {
        equalities.primaries.put(top, anno);
      }
    }
  }

  /**
   * Add a constraint indicating that target is a supertype of subtype in the given qualifier
   * hierarchies.
   *
   * @param hierarchies a set of TOP annotations
   */
  public void addTargetSupertype(
      final TypeVariable target, final TypeVariable subtype, AnnotationMirrorSet hierarchies) {
    final Supertypes supertypes = targetToRecords.get(target).supertypes;
    final AnnotationMirrorSet supertypeTops =
        supertypes.targets.computeIfAbsent(subtype, __ -> new AnnotationMirrorSet());
    supertypeTops.addAll(hierarchies);
  }

  /**
   * Add a constraint indicating that target is a supertype of subtype in the given qualifier
   * hierarchies.
   *
   * @param hierarchies a set of TOP annotations
   */
  public void addTypeSupertype(
      final TypeVariable target,
      final AnnotatedTypeMirror subtype,
      AnnotationMirrorSet hierarchies) {
    final Supertypes supertypes = targetToRecords.get(target).supertypes;
    final AnnotationMirrorSet supertypeTops =
        supertypes.types.computeIfAbsent(subtype, __ -> new AnnotationMirrorSet());
    supertypeTops.addAll(hierarchies);
  }

  /**
   * Add a constraint indicating that target's primary annotations are subtypes of the given
   * annotations.
   */
  public void addPrimarySupertype(
      final TypeVariable target,
      QualifierHierarchy qualifierHierarchy,
      final AnnotationMirrorSet annos) {
    final Supertypes supertypes = targetToRecords.get(target).supertypes;
    for (final AnnotationMirror anno : annos) {
      final AnnotationMirror top = qualifierHierarchy.getTopAnnotation(anno);
      AnnotationMirrorSet entries =
          supertypes.primaries.computeIfAbsent(top, __ -> new AnnotationMirrorSet());
      entries.add(anno);
    }
  }

  /**
   * Add a constraint indicating that target is a subtype of supertype in the given qualifier
   * hierarchies.
   *
   * @param hierarchies a set of TOP annotations
   */
  public void addTargetSubtype(
      final TypeVariable target, final TypeVariable supertype, AnnotationMirrorSet hierarchies) {
    final Subtypes subtypes = targetToRecords.get(target).subtypes;
    final AnnotationMirrorSet subtypesTops =
        subtypes.targets.computeIfAbsent(supertype, __ -> new AnnotationMirrorSet());
    subtypesTops.addAll(hierarchies);
  }

  /**
   * Add a constraint indicating that target is a subtype of supertype in the given qualifier
   * hierarchies.
   *
   * @param hierarchies a set of TOP annotations
   */
  public void addTypeSubtype(
      final TypeVariable target,
      final AnnotatedTypeMirror supertype,
      AnnotationMirrorSet hierarchies) {
    final Subtypes subtypes = targetToRecords.get(target).subtypes;
    final AnnotationMirrorSet subtypesTops =
        subtypes.types.computeIfAbsent(supertype, __ -> new AnnotationMirrorSet());
    subtypesTops.addAll(hierarchies);
  }

  /**
   * Add a constraint indicating that target's primary annotations are subtypes of the given
   * annotations.
   */
  public void addPrimarySubtypes(
      final TypeVariable target,
      QualifierHierarchy qualifierHierarchy,
      final AnnotationMirrorSet annos) {
    final Subtypes subtypes = targetToRecords.get(target).subtypes;
    for (final AnnotationMirror anno : annos) {
      final AnnotationMirror top = qualifierHierarchy.getTopAnnotation(anno);
      AnnotationMirrorSet entries =
          subtypes.primaries.computeIfAbsent(top, __ -> new AnnotationMirrorSet());
      entries.add(anno);
    }
  }

  /**
   * Add a constraint indicating that target is equal to type in the given hierarchies.
   *
   * @param hierarchies a set of TOP annotations
   */
  public void addTypeEqualities(
      TypeVariable target, AnnotatedTypeMirror type, AnnotationMirrorSet hierarchies) {
    final Equalities equalities = targetToRecords.get(target).equalities;
    final AnnotationMirrorSet equalityTops =
        equalities.types.computeIfAbsent(type, __ -> new AnnotationMirrorSet());
    equalityTops.addAll(hierarchies);
  }
}
