package org.checkerframework.framework.util.dependenttypes;

import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.checkerframework.checker.formatter.qual.ConversionCategory;
import org.checkerframework.checker.formatter.qual.Format;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.framework.util.JavaExpressionParseUtil.JavaExpressionParseException;
import org.checkerframework.javacutil.BugInCF;

/**
 * Helper class for creating dependent type annotation error strings.
 *
 * <p><b>IMPORTANT:</b> This is not an Exception. It is a regular class that is returned, not
 * thrown. The errors are not thrown so that they are only reported once rather than every time the
 * annotation is parsed. See {@link DependentTypesHelper} for more details.
 */
public class DependentTypesError {

  /// Static fields

  /** How elements of this class are formatted. */
  @SuppressWarnings("InlineFormatString") // https://github.com/google/error-prone/issues/1650
  private static final String FORMAT_STRING = "[error for expression: %s; error: %s]";
  /** Regular expression for unparsing string representations of this class (gross). */
  private static final Pattern ERROR_PATTERN =
      Pattern.compile("\\[error for expression: (.*); error: (.*)\\]");
  /**
   * Returns whether or not the given expression string is an error. That is, whether it is a string
   * that was generated by this class.
   *
   * @param expression expression string to test
   * @return whether or not the given expressions string is an error
   */
  public static boolean isExpressionError(String expression) {
    return expression.startsWith("[error");
  }

  /** How to format warnings about use of formal parameter name. */
  public static final @Format({ConversionCategory.INT, ConversionCategory.GENERAL}) String
      FORMAL_PARAM_NAME_STRING = "Use \"#%d\" rather than \"%s\"";
  /** Matches warnings about use of formal parameter name. */
  private static final Pattern FORMAL_PARAM_NAME_PATTERN =
      Pattern.compile("^'([a-zA-Z_$][a-zA-Z0-9_$]*)' because (Use \"#\\d+\" rather than \"\\1\")$");

  /// Instance fields

  /** The expression that is unparsable or otherwise problematic. */
  public final String expression;
  /** An error message about that expression. */
  public final String error;

  /// Constructors and methods

  /**
   * Create a DependentTypesError for the given expression and error message.
   *
   * @param expression the incorrect Java expression
   * @param error an error message about the expression
   */
  public DependentTypesError(String expression, String error) {
    this.expression = expression;
    this.error = error;
  }

  /**
   * Create a DependentTypesError for the given expression and exception.
   *
   * @param expression the incorrect Java expression
   * @param e wraps an error message about the expression
   */
  public DependentTypesError(String expression, JavaExpressionParseException e) {
    this.expression = expression;
    this.error = e.getDiagMessage().getArgs()[0].toString();
  }

  /**
   * Create a DependentTypesError by parsing a printed one.
   *
   * @param formattedError the toString() representation of a DependentTypesError
   */
  public static DependentTypesError unparse(String formattedError) {
    Matcher matcher = ERROR_PATTERN.matcher(formattedError);
    if (matcher.matches()) {
      assert matcher.groupCount() == 2;
      return new DependentTypesError(matcher.group(1), matcher.group(2));
    } else {
      throw new BugInCF("Cannot unparse: " + formattedError);
    }
  }

  @Override
  public boolean equals(@Nullable Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }

    DependentTypesError that = (DependentTypesError) o;

    return expression.equals(that.expression) && error.equals(that.error);
  }

  @Override
  public int hashCode() {
    return Objects.hash(expression, error);
  }

  @Override
  public String toString() {
    return String.format(FORMAT_STRING, expression, error);
  }

  /**
   * Like toString, but uses better formatting sometimes. Use this only for the final output,
   * because of the design that hides error messages in toString().
   */
  public String format() {
    Matcher m = FORMAL_PARAM_NAME_PATTERN.matcher(error);
    if (m.matches()) {
      return m.group(2);
    }
    return toString();
  }
}
