package org.checkerframework.checker.formatter;

import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.IdentifierTree;
import com.sun.source.tree.MethodInvocationTree;
import com.sun.source.tree.MethodTree;
import com.sun.source.tree.Tree;
import com.sun.source.tree.VariableTree;
import java.util.List;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import org.checkerframework.checker.compilermsgs.qual.CompilerMessageKey;
import org.checkerframework.checker.formatter.FormatterTreeUtil.FormatCall;
import org.checkerframework.checker.formatter.FormatterTreeUtil.InvocationType;
import org.checkerframework.checker.formatter.FormatterTreeUtil.Result;
import org.checkerframework.checker.formatter.qual.ConversionCategory;
import org.checkerframework.checker.formatter.qual.FormatMethod;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.common.basetype.BaseTypeChecker;
import org.checkerframework.common.basetype.BaseTypeVisitor;
import org.checkerframework.common.wholeprograminference.WholeProgramInference;
import org.checkerframework.framework.type.AnnotatedTypeMirror;
import org.checkerframework.javacutil.AnnotationUtils;
import org.checkerframework.javacutil.BugInCF;
import org.checkerframework.javacutil.ElementUtils;
import org.checkerframework.javacutil.TreePathUtil;
import org.checkerframework.javacutil.TreeUtils;
import org.checkerframework.javacutil.TypesUtils;

/**
 * Whenever a format method invocation is found in the syntax tree, checks are performed as
 * specified in the Format String Checker manual.
 *
 * @checker_framework.manual #formatter-guarantees Format String Checker
 */
public class FormatterVisitor extends BaseTypeVisitor<FormatterAnnotatedTypeFactory> {
  public FormatterVisitor(BaseTypeChecker checker) {
    super(checker);
  }

  @Override
  public Void visitMethod(MethodTree node, Void p) {
    ExecutableElement methodElement = TreeUtils.elementFromDeclaration(node);
    if (atypeFactory.getDeclAnnotation(methodElement, FormatMethod.class) != null) {
      int formatStringIndex = FormatterVisitor.formatStringIndex(methodElement);
      if (formatStringIndex == -1) {
        checker.reportError(node, "format.method", methodElement.getSimpleName());
      }
    }
    return super.visitMethod(node, p);
  }

  @Override
  public Void visitMethodInvocation(MethodInvocationTree node, Void p) {
    FormatterTreeUtil ftu = atypeFactory.treeUtil;
    FormatCall fc = ftu.create(node, atypeFactory);
    if (fc != null) {
      MethodTree enclosingMethod =
          TreePathUtil.enclosingMethod(atypeFactory.getPath(fc.invocationTree));

      Result<String> errMissingFormat = fc.errMissingFormatAnnotation();
      if (errMissingFormat != null) {
        // The string's type has no @Format annotation.
        if (isWrappedFormatCall(fc, enclosingMethod)) {
          // Nothing to do, because call is legal.
        } else {
          // I.1
          ftu.failure(errMissingFormat, "format.string", errMissingFormat.value());
        }
      } else {
        // The string has a @Format annotation.
        Result<InvocationType> invc = fc.getInvocationType();
        ConversionCategory[] formatCats = fc.getFormatCategories();
        switch (invc.value()) {
          case VARARG:
            Result<TypeMirror>[] argTypes = fc.getArgTypes();
            int argl = argTypes.length;
            int formatl = formatCats.length;
            if (argl < formatl) {
              // For assignments, format.missing.arguments is issued from commonAssignmentCheck.
              // II.1
              ftu.failure(invc, "format.missing.arguments", formatl, argl);
            } else {
              if (argl > formatl) {
                // II.2
                ftu.warning(invc, "format.excess.arguments", formatl, argl);
              }
              for (int i = 0; i < formatl; ++i) {
                ConversionCategory formatCat = formatCats[i];
                Result<TypeMirror> arg = argTypes[i];
                TypeMirror argType = arg.value();

                switch (formatCat) {
                  case UNUSED:
                    // I.2
                    ftu.warning(arg, "format.argument.unused", " " + (1 + i));
                    break;
                  case NULL:
                    // I.3
                    if (argType.getKind() == TypeKind.NULL) {
                      ftu.warning(arg, "format.specifier.null", " " + (1 + i));
                    } else {
                      ftu.failure(arg, "format.specifier.null", " " + (1 + i));
                    }
                    break;
                  case GENERAL:
                    break;
                  default:
                    if (!fc.isValidArgument(formatCat, argType)) {
                      // II.3
                      ExecutableElement method = TreeUtils.elementFromUse(node);
                      CharSequence methodName = ElementUtils.getSimpleNameOrDescription(method);
                      ftu.failure(
                          arg, "argument", "in varargs position", methodName, argType, formatCat);
                    }
                    break;
                }
              }
            }
            break;
          case ARRAY:
            // III
            if (!isWrappedFormatCall(fc, enclosingMethod)) {
              ftu.warning(invc, "format.indirect.arguments");
            }
            // TODO:  If it is explict array construction, such as "new Object[] {
            // ... }", then we could treat it like the VARARGS case, analyzing each
            // argument.  "new array" is probably rare, in the varargs position.
            // fall through
          case NULLARRAY:
            for (ConversionCategory cat : formatCats) {
              if (cat == ConversionCategory.NULL) {
                // I.3
                if (invc.value() == FormatterTreeUtil.InvocationType.NULLARRAY) {
                  ftu.warning(invc, "format.specifier.null", "");
                } else {
                  ftu.failure(invc, "format.specifier.null", "");
                }
              }
              if (cat == ConversionCategory.UNUSED) {
                // I.2
                ftu.warning(invc, "format.argument.unused", "");
              }
            }
            break;
        }
      }

      // Support -Ainfer command-line argument.
      WholeProgramInference wpi = atypeFactory.getWholeProgramInference();
      if (wpi != null && forwardsArguments(node, enclosingMethod)) {
        wpi.addMethodDeclarationAnnotation(
            TreeUtils.elementFromDeclaration(enclosingMethod), atypeFactory.FORMATMETHOD);
      }
    }
    return super.visitMethodInvocation(node, p);
  }

  /**
   * Returns true if {@code fc} is within a method m annotated as {@code @FormatMethod}, and fc's
   * arguments are m's formal parameters. In other words, fc forwards m's arguments to another
   * format method.
   *
   * @param fc an invocation of a format method
   * @param enclosingMethod the method that contains the call
   * @return true if {@code fc} is a call to a format method that forwards its containing method's
   *     arguments
   */
  private boolean isWrappedFormatCall(FormatCall fc, @Nullable MethodTree enclosingMethod) {
    if (enclosingMethod == null) {
      return false;
    }
    ExecutableElement enclosingMethodElement = TreeUtils.elementFromDeclaration(enclosingMethod);
    boolean withinFormatMethod =
        (atypeFactory.getDeclAnnotation(enclosingMethodElement, FormatMethod.class) != null);
    return withinFormatMethod && forwardsArguments(fc.invocationTree, enclosingMethod);
  }

  /**
   * Returns true if {@code invocationTree}'s arguments are {@code enclosingMethod}'s formal
   * parameters. In other words, {@code invocationTree} forwards {@code enclosingMethod}'s
   * arguments.
   *
   * <p>Only arguments from the first String formal parameter onward count. Returns false if there
   * is no String formal parameter.
   *
   * @param invocationTree an invocation of a method
   * @param enclosingMethod the method that contains the call
   * @return true if {@code invocationTree} is a call to a method that forwards its containing
   *     method's arguments
   */
  private boolean forwardsArguments(
      MethodInvocationTree invocationTree, @Nullable MethodTree enclosingMethod) {

    if (enclosingMethod == null) {
      return false;
    }

    ExecutableElement enclosingMethodElement = TreeUtils.elementFromDeclaration(enclosingMethod);
    int paramIndex = formatStringIndex(enclosingMethodElement);
    if (paramIndex == -1) {
      return false;
    }

    ExecutableElement calledMethodElement = TreeUtils.elementFromUse(invocationTree);
    int callIndex = formatStringIndex(calledMethodElement);
    if (callIndex == -1) {
      throw new BugInCF(
          "Method "
              + calledMethodElement
              + " is annotated @FormatMethod but has no String formal parameter");
    }

    List<? extends ExpressionTree> args = invocationTree.getArguments();
    List<? extends VariableTree> params = enclosingMethod.getParameters();

    if (params.size() - paramIndex != args.size() - callIndex) {
      return false;
    }
    while (paramIndex < params.size()) {
      ExpressionTree argTree = args.get(callIndex);
      if (argTree.getKind() != Tree.Kind.IDENTIFIER) {
        return false;
      }
      VariableTree param = params.get(paramIndex);
      if (param.getName() != ((IdentifierTree) argTree).getName()) {
        return false;
      }
      paramIndex++;
      callIndex++;
    }

    return true;
  }

  // TODO: Should this be the last String argument?  That would require that every method
  // annotated with @FormatMethod uses varargs syntax.
  /**
   * Returns the index of the format string of a method: the first formal parameter with declared
   * type String.
   *
   * @param m a method
   * @return the index of the last String formal parameter, or -1 if none
   */
  public static int formatStringIndex(ExecutableElement m) {
    List<? extends VariableElement> params = m.getParameters();
    for (int i = 0; i < params.size(); i++) {
      if (TypesUtils.isString(params.get(i).asType())) {
        return i;
      }
    }
    return -1;
  }

  @Override
  protected void commonAssignmentCheck(
      AnnotatedTypeMirror varType,
      AnnotatedTypeMirror valueType,
      Tree valueTree,
      @CompilerMessageKey String errorKey,
      Object... extraArgs) {
    super.commonAssignmentCheck(varType, valueType, valueTree, errorKey, extraArgs);

    AnnotationMirror rhs = valueType.getAnnotationInHierarchy(atypeFactory.UNKNOWNFORMAT);
    AnnotationMirror lhs = varType.getAnnotationInHierarchy(atypeFactory.UNKNOWNFORMAT);

    // From the manual: "It is legal to use a format string with fewer format specifiers
    // than required, but a warning is issued."
    // The format.missing.arguments warning is issued here for assignments.
    // For method calls, it is issued in visitMethodInvocation.
    if (rhs != null
        && lhs != null
        && AnnotationUtils.areSameByName(rhs, FormatterAnnotatedTypeFactory.FORMAT_NAME)
        && AnnotationUtils.areSameByName(lhs, FormatterAnnotatedTypeFactory.FORMAT_NAME)) {
      ConversionCategory[] rhsArgTypes = atypeFactory.treeUtil.formatAnnotationToCategories(rhs);
      ConversionCategory[] lhsArgTypes = atypeFactory.treeUtil.formatAnnotationToCategories(lhs);

      if (rhsArgTypes.length < lhsArgTypes.length) {
        checker.reportWarning(
            valueTree, "format.missing.arguments", varType.toString(), valueType.toString());
      }
    }
  }
}
