package org.checkerframework.checker.i18nformatter.qual;

import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.StringJoiner;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.framework.qual.AnnotatedFor;

/**
 * Elements of this enumeration are used in a {@link I18nFormat} annotation to indicate the valid
 * types that may be passed as a format parameter. For example:
 *
 * <pre>{@literal @}I18nFormat({GENERAL, NUMBER}) String f = "{0}{1, number}";
 * MessageFormat.format(f, "Example", 0) // valid</pre>
 *
 * The annotation indicates that the format string requires any object as the first parameter
 * ({@link I18nConversionCategory#GENERAL}) and a number as the second parameter ({@link
 * I18nConversionCategory#NUMBER}).
 *
 * @checker_framework.manual #i18n-formatter-checker Internationalization Format String Checker
 */
@AnnotatedFor("nullness")
public enum I18nConversionCategory {

  /**
   * Use if a parameter is not used by the formatter. For example, in
   *
   * <pre>
   * MessageFormat.format(&quot;{1}&quot;, a, b);
   * </pre>
   *
   * only the second argument ("b") is used. The first argument ("a") is ignored.
   */
  UNUSED(null /* everything */, null),

  /** Use if the parameter can be of any type. */
  GENERAL(null /* everything */, null),

  /** Use if the parameter can be of date, time, or number types. */
  DATE(new Class<?>[] {Date.class, Number.class}, new String[] {"date", "time"}),

  /**
   * Use if the parameter can be of number or choice types. An example of choice:
   *
   * <pre>{@code
   * format("{0, choice, 0#zero|1#one|1<{0, number} is more than 1}", 2)
   * }</pre>
   *
   * This will print "2 is more than 1".
   */
  NUMBER(new Class<?>[] {Number.class}, new String[] {"number", "choice"});

  @SuppressWarnings("ImmutableEnumChecker") // TODO: clean this up!
  public final Class<?> @Nullable [] types;

  @SuppressWarnings("ImmutableEnumChecker") // TODO: clean this up!
  public final String @Nullable [] strings;

  I18nConversionCategory(Class<?> @Nullable [] types, String @Nullable [] strings) {
    this.types = types;
    this.strings = strings;
  }

  /** Used by {@link #stringToI18nConversionCategory}. */
  static I18nConversionCategory[] namedCategories = new I18nConversionCategory[] {DATE, NUMBER};

  /**
   * Creates a conversion cagetogry from a string name.
   *
   * <pre>
   * I18nConversionCategory.stringToI18nConversionCategory("number") == I18nConversionCategory.NUMBER;
   * </pre>
   *
   * @return the I18nConversionCategory associated with the given string
   */
  @SuppressWarnings(
      "nullness:iterating.over.nullable") // in namedCategories, `strings` field is non-null
  public static I18nConversionCategory stringToI18nConversionCategory(String string) {
    string = string.toLowerCase();
    for (I18nConversionCategory v : namedCategories) {
      for (String s : v.strings) {
        if (s.equals(string)) {
          return v;
        }
      }
    }
    throw new IllegalArgumentException("Invalid format type " + string);
  }

  private static <E> Set<E> arrayToSet(E[] a) {
    return new HashSet<>(Arrays.asList(a));
  }

  /**
   * Return true if a is a subset of b.
   *
   * @return true if a is a subset of b
   */
  public static boolean isSubsetOf(I18nConversionCategory a, I18nConversionCategory b) {
    return intersect(a, b) == a;
  }

  /**
   * Returns the intersection of the two given I18nConversionCategories.
   *
   * <blockquote>
   *
   * <pre>
   * I18nConversionCategory.intersect(DATE, NUMBER) == NUMBER;
   * </pre>
   *
   * </blockquote>
   */
  public static I18nConversionCategory intersect(
      I18nConversionCategory a, I18nConversionCategory b) {
    if (a == UNUSED) {
      return b;
    }
    if (b == UNUSED) {
      return a;
    }
    if (a == GENERAL) {
      return b;
    }
    if (b == GENERAL) {
      return a;
    }

    @SuppressWarnings("nullness:argument" // types field  is only null in UNUSED and GENERAL
    )
    Set<Class<?>> as = arrayToSet(a.types);
    @SuppressWarnings("nullness:argument" // types field  is only null in UNUSED and GENERAL
    )
    Set<Class<?>> bs = arrayToSet(b.types);
    as.retainAll(bs); // intersection
    for (I18nConversionCategory v : new I18nConversionCategory[] {DATE, NUMBER}) {
      @SuppressWarnings("nullness:argument") // in those values, `types` field is non-null
      Set<Class<?>> vs = arrayToSet(v.types);
      if (vs.equals(as)) {
        return v;
      }
    }
    throw new RuntimeException();
  }

  /**
   * Returns the union of the two given I18nConversionCategories.
   *
   * <pre>
   * I18nConversionCategory.intersect(DATE, NUMBER) == DATE;
   * </pre>
   */
  public static I18nConversionCategory union(I18nConversionCategory a, I18nConversionCategory b) {
    if (a == UNUSED || b == UNUSED) {
      return UNUSED;
    }
    if (a == GENERAL || b == GENERAL) {
      return GENERAL;
    }
    if (a == DATE || b == DATE) {
      return DATE;
    }
    return NUMBER;
  }

  /**
   * Returns true if {@code argType} can be an argument used by this format specifier.
   *
   * @param argType an argument type
   * @return true if {@code argType} can be an argument used by this format specifier
   */
  public boolean isAssignableFrom(Class<?> argType) {
    if (types == null) {
      return true;
    }
    if (argType == void.class) {
      return true;
    }
    for (Class<?> c : types) {
      if (c.isAssignableFrom(argType)) {
        return true;
      }
    }
    return false;
  }

  /** Returns a pretty printed {@link I18nConversionCategory}. */
  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder(this.name());
    if (this.types == null) {
      sb.append(" conversion category (all types)");
    } else {
      StringJoiner sj = new StringJoiner(", ", " conversion category (one of: ", ")");
      for (Class<?> cls : this.types) {
        sj.add(cls.getCanonicalName());
      }
      sb.append(sj);
    }
    return sb.toString();
  }
}
