package org.checkerframework.checker.fenum;

import com.sun.source.tree.BinaryTree;
import com.sun.source.tree.CaseTree;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.NewClassTree;
import com.sun.source.tree.SwitchTree;
import com.sun.source.tree.Tree;
import java.util.Collections;
import java.util.Set;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.ExecutableElement;
import org.checkerframework.common.basetype.BaseTypeChecker;
import org.checkerframework.common.basetype.BaseTypeVisitor;
import org.checkerframework.framework.type.AnnotatedTypeMirror;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType;
import org.checkerframework.framework.type.QualifierHierarchy;
import org.checkerframework.javacutil.TreeUtils;

public class FenumVisitor extends BaseTypeVisitor<FenumAnnotatedTypeFactory> {
  public FenumVisitor(BaseTypeChecker checker) {
    super(checker);
  }

  @Override
  public Void visitBinary(BinaryTree node, Void p) {
    if (!TreeUtils.isStringConcatenation(node)) {
      // TODO: ignore string concatenations

      // The Fenum Checker is only concerned with primitive types, so just check that
      // the primary annotations are equivalent.
      AnnotatedTypeMirror lhsAtm = atypeFactory.getAnnotatedType(node.getLeftOperand());
      AnnotatedTypeMirror rhsAtm = atypeFactory.getAnnotatedType(node.getRightOperand());

      Set<AnnotationMirror> lhs = lhsAtm.getEffectiveAnnotations();
      Set<AnnotationMirror> rhs = rhsAtm.getEffectiveAnnotations();
      QualifierHierarchy qualHierarchy = atypeFactory.getQualifierHierarchy();
      if (!(qualHierarchy.isSubtype(lhs, rhs) || qualHierarchy.isSubtype(rhs, lhs))) {
        checker.reportError(node, "binary", lhsAtm, rhsAtm);
      }
    }
    return super.visitBinary(node, p);
  }

  @Override
  public Void visitSwitch(SwitchTree node, Void p) {
    ExpressionTree expr = node.getExpression();
    AnnotatedTypeMirror exprType = atypeFactory.getAnnotatedType(expr);

    for (CaseTree caseExpr : node.getCases()) {
      ExpressionTree realCaseExpr = caseExpr.getExpression();
      if (realCaseExpr != null) {
        AnnotatedTypeMirror caseType = atypeFactory.getAnnotatedType(realCaseExpr);

        // There is currently no "switch" message key, so it is treated
        // identically to "type.incompatible".
        this.commonAssignmentCheck(exprType, caseType, caseExpr, "type.incompatible");
      }
    }
    return super.visitSwitch(node, p);
  }

  @Override
  protected void checkConstructorInvocation(
      AnnotatedDeclaredType dt, AnnotatedExecutableType constructor, NewClassTree src) {
    // Ignore the default annotation on the constructor
  }

  @Override
  protected void checkConstructorResult(
      AnnotatedExecutableType constructorType, ExecutableElement constructorElement) {
    // Skip this check
  }

  @Override
  protected Set<? extends AnnotationMirror> getExceptionParameterLowerBoundAnnotations() {
    return Collections.singleton(atypeFactory.FENUM_UNQUALIFIED);
  }

  // TODO: should we require a match between switch expression and cases?

  @Override
  public boolean isValidUse(
      AnnotatedDeclaredType declarationType, AnnotatedDeclaredType useType, Tree tree) {
    // The checker calls this method to compare the annotation used in a type to the modifier it
    // adds to the class declaration. As our default modifier is FenumBottom, this results in an
    // error when a non-subtype is used. Can we use FenumTop as default instead?
    return true;
  }
}
