package org.checkerframework.checker.i18nformatter.util;

import java.text.ChoiceFormat;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.IllegalFormatException;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.checkerframework.checker.i18nformatter.qual.I18nChecksFormat;
import org.checkerframework.checker.i18nformatter.qual.I18nConversionCategory;
import org.checkerframework.checker.i18nformatter.qual.I18nValidFormat;
import org.checkerframework.checker.interning.qual.InternedDistinct;
import org.checkerframework.checker.nullness.qual.EnsuresNonNull;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.checker.nullness.qual.RequiresNonNull;
import org.checkerframework.framework.qual.AnnotatedFor;

/**
 * This class provides a collection of utilities to ease working with i18n format strings.
 *
 * @checker_framework.manual #i18n-formatter-checker Internationalization Format String Checker
 */
@AnnotatedFor("nullness")
public class I18nFormatUtil {

  /**
   * Throws an exception if the format is not syntactically valid.
   *
   * @param format the format string to parse
   */
  @SuppressWarnings("nullness:argument") // It's not documented, but passing null as the
  // argument array is supported.
  public static void tryFormatSatisfiability(String format) throws IllegalFormatException {
    MessageFormat.format(format, (Object[]) null);
  }

  /**
   * Returns a {@link I18nConversionCategory} for every conversion found in the format string.
   *
   * @param format the format string to parse
   * @throws IllegalFormatException if the format is not syntactically valid
   */
  public static I18nConversionCategory[] formatParameterCategories(String format)
      throws IllegalFormatException {
    tryFormatSatisfiability(format);
    I18nConversion[] cs = MessageFormatParser.parse(format);

    int maxIndex = -1;
    Map<Integer, I18nConversionCategory> conv = new HashMap<>(cs.length);

    for (I18nConversion c : cs) {
      int index = c.index;
      Integer indexKey = index;
      conv.put(
          indexKey,
          I18nConversionCategory.intersect(
              c.category,
              conv.containsKey(indexKey) ? conv.get(indexKey) : I18nConversionCategory.UNUSED));
      maxIndex = Math.max(maxIndex, index);
    }

    I18nConversionCategory[] res = new I18nConversionCategory[maxIndex + 1];
    for (int i = 0; i <= maxIndex; i++) {
      Integer indexKey = i;
      res[i] = conv.containsKey(indexKey) ? conv.get(indexKey) : I18nConversionCategory.UNUSED;
    }
    return res;
  }

  /**
   * Returns true if the format string is satisfiable, and if the format's parameters match the
   * passed {@link I18nConversionCategory}s. Otherwise an error is thrown.
   *
   * @param format a format string
   * @param cc a list of expected categories for the string's format specifiers
   * @return true if the format string's specifiers are the given categories, in order
   */
  // TODO introduce more such functions, see RegexUtil for examples
  @I18nChecksFormat
  public static boolean hasFormat(String format, I18nConversionCategory... cc) {
    I18nConversionCategory[] fcc = formatParameterCategories(format);
    if (fcc.length != cc.length) {
      return false;
    }

    for (int i = 0; i < cc.length; i++) {
      if (!I18nConversionCategory.isSubsetOf(cc[i], fcc[i])) {
        return false;
      }
    }
    return true;
  }

  @I18nValidFormat
  public static boolean isFormat(String format) {
    try {
      formatParameterCategories(format);
    } catch (Exception e) {
      return false;
    }
    return true;
  }

  private static class I18nConversion {
    public int index;
    public I18nConversionCategory category;

    public I18nConversion(int index, I18nConversionCategory category) {
      this.index = index;
      this.category = category;
    }

    @Override
    public String toString() {
      return category.toString() + "(index: " + index + ")";
    }
  }

  private static class MessageFormatParser {

    public static int maxOffset;

    /** The locale to use for formatting numbers and dates. Is set in {@link #parse}. */
    private static @MonotonicNonNull Locale locale;

    /** An array of formatters, which are used to format the arguments. Is set in {@link #parse}. */
    private static @MonotonicNonNull List<I18nConversionCategory> categories;

    /**
     * The argument numbers corresponding to each formatter. (The formatters are stored in the order
     * they occur in the pattern, not in the order in which the arguments are specified.) Is set in
     * {@link #parse}.
     */
    private static @MonotonicNonNull List<Integer> argumentIndices;

    // I think this means the number of format specifiers in the format string.
    /** The number of subformats. */
    private static int numFormat;

    // Indices for segments
    private static final int SEG_RAW = 0;
    private static final int SEG_INDEX = 1;
    private static final int SEG_TYPE = 2;
    private static final int SEG_MODIFIER = 3; // modifier or subformat

    // Indices for type keywords
    private static final int TYPE_NULL = 0;
    private static final int TYPE_NUMBER = 1;
    private static final int TYPE_DATE = 2;
    private static final int TYPE_TIME = 3;
    private static final int TYPE_CHOICE = 4;

    private static final String[] TYPE_KEYWORDS = {"", "number", "date", "time", "choice"};

    // Indices for number modifiers
    private static final int MODIFIER_DEFAULT = 0; // common in number and date-time
    private static final int MODIFIER_CURRENCY = 1;
    private static final int MODIFIER_PERCENT = 2;
    private static final int MODIFIER_INTEGER = 3;

    private static final String[] NUMBER_MODIFIER_KEYWORDS = {"", "currency", "percent", "integer"};

    private static final String[] DATE_TIME_MODIFIER_KEYWORDS = {
      "", "short", "medium", "long", "full"
    };

    @EnsuresNonNull({"categories", "argumentIndices", "locale"})
    public static I18nConversion[] parse(String pattern) {
      MessageFormatParser.categories = new ArrayList<>();
      MessageFormatParser.argumentIndices = new ArrayList<>();
      MessageFormatParser.locale = Locale.getDefault(Locale.Category.FORMAT);
      applyPattern(pattern);

      I18nConversion[] ret = new I18nConversion[MessageFormatParser.numFormat];
      for (int i = 0; i < MessageFormatParser.numFormat; i++) {
        ret[i] = new I18nConversion(argumentIndices.get(i), categories.get(i));
      }
      return ret;
    }

    @SuppressWarnings("nullness:dereference.of.nullable") // complex rules for segments[i]
    @RequiresNonNull({"argumentIndices", "categories", "locale"})
    private static void applyPattern(String pattern) {
      @Nullable StringBuilder[] segments = new StringBuilder[4];
      // Allocate only segments[SEG_RAW] here. The rest are
      // allocated on demand.
      segments[SEG_RAW] = new StringBuilder();

      int part = SEG_RAW;
      MessageFormatParser.numFormat = 0;
      boolean inQuote = false;
      int braceStack = 0;
      maxOffset = -1;
      for (int i = 0; i < pattern.length(); ++i) {
        char ch = pattern.charAt(i);
        if (part == SEG_RAW) {
          if (ch == '\'') {
            if (i + 1 < pattern.length() && pattern.charAt(i + 1) == '\'') {
              segments[part].append(ch); // handle doubles
              ++i;
            } else {
              inQuote = !inQuote;
            }
          } else if (ch == '{' && !inQuote) {
            part = SEG_INDEX;
            if (segments[SEG_INDEX] == null) {
              segments[SEG_INDEX] = new StringBuilder();
            }
          } else {
            segments[part].append(ch);
          }
        } else {
          if (inQuote) { // just copy quotes in parts
            segments[part].append(ch);
            if (ch == '\'') {
              inQuote = false;
            }
          } else {
            switch (ch) {
              case ',':
                if (part < SEG_MODIFIER) {
                  if (segments[++part] == null) {
                    segments[part] = new StringBuilder();
                  }
                } else {
                  segments[part].append(ch);
                }
                break;
              case '{':
                ++braceStack;
                segments[part].append(ch);
                break;
              case '}':
                if (braceStack == 0) {
                  part = SEG_RAW;
                  makeFormat(numFormat, segments);
                  numFormat++;
                  // throw away other segments
                  segments[SEG_INDEX] = null;
                  segments[SEG_TYPE] = null;
                  segments[SEG_MODIFIER] = null;
                } else {
                  --braceStack;
                  segments[part].append(ch);
                }
                break;
              case ' ':
                // Skip any leading space chars for SEG_TYPE.
                if (part != SEG_TYPE || segments[SEG_TYPE].length() > 0) {
                  segments[part].append(ch);
                }
                break;
              case '\'':
                inQuote = true;
                segments[part].append(ch);
                break;
              default:
                segments[part].append(ch);
                break;
            }
          }
        }
      }
      if (braceStack == 0 && part != 0) {
        maxOffset = -1;
        throw new IllegalArgumentException("Unmatched braces in the pattern");
      }
    }

    /** Side-effects {@code categories} field, adding to it an I18nConversionCategory. */
    @RequiresNonNull({"argumentIndices", "categories", "locale"})
    private static void makeFormat(int offsetNumber, @Nullable StringBuilder[] textSegments) {
      String[] segments = new String[textSegments.length];
      for (int i = 0; i < textSegments.length; i++) {
        StringBuilder oneseg = textSegments[i];
        segments[i] = (oneseg != null) ? oneseg.toString() : "";
      }

      // get the argument number
      int argumentNumber;
      try {
        argumentNumber = Integer.parseInt(segments[SEG_INDEX]); // always
        // unlocalized!
      } catch (NumberFormatException e) {
        throw new IllegalArgumentException(
            "can't parse argument number: " + segments[SEG_INDEX], e);
      }
      if (argumentNumber < 0) {
        throw new IllegalArgumentException("negative argument number: " + argumentNumber);
      }

      int oldMaxOffset = maxOffset;
      maxOffset = offsetNumber;
      argumentIndices.add(argumentNumber);

      // now get the format
      I18nConversionCategory category = null;
      if (segments[SEG_TYPE].length() != 0) {
        int type = findKeyword(segments[SEG_TYPE], TYPE_KEYWORDS);
        switch (type) {
          case TYPE_NULL:
            category = I18nConversionCategory.GENERAL;
            break;
          case TYPE_NUMBER:
            switch (findKeyword(segments[SEG_MODIFIER], NUMBER_MODIFIER_KEYWORDS)) {
              case MODIFIER_DEFAULT:
              case MODIFIER_CURRENCY:
              case MODIFIER_PERCENT:
              case MODIFIER_INTEGER:
                break;
              default: // DecimalFormat pattern
                try {
                  new DecimalFormat(
                      segments[SEG_MODIFIER], DecimalFormatSymbols.getInstance(locale));
                } catch (IllegalArgumentException e) {
                  maxOffset = oldMaxOffset;
                  // invalid decimal subformat pattern
                  throw e;
                }
                break;
            }
            category = I18nConversionCategory.NUMBER;
            break;
          case TYPE_DATE:
          case TYPE_TIME:
            int mod = findKeyword(segments[SEG_MODIFIER], DATE_TIME_MODIFIER_KEYWORDS);
            if (mod >= 0 && mod < DATE_TIME_MODIFIER_KEYWORDS.length) {
              // nothing to do
            } else {
              // SimpleDateFormat pattern
              try {
                new SimpleDateFormat(segments[SEG_MODIFIER], locale);
              } catch (IllegalArgumentException e) {
                maxOffset = oldMaxOffset;
                // invalid date subformat pattern
                throw e;
              }
            }
            category = I18nConversionCategory.DATE;
            break;
          case TYPE_CHOICE:
            if (segments[SEG_MODIFIER].length() == 0) {
              throw new IllegalArgumentException(
                  "Choice Pattern requires Subformat Pattern: " + segments[SEG_MODIFIER]);
            }
            try {
              // ChoiceFormat pattern
              new ChoiceFormat(segments[SEG_MODIFIER]);
            } catch (Exception e) {
              maxOffset = oldMaxOffset;
              // invalid choice subformat pattern
              throw new IllegalArgumentException(
                  "Choice Pattern incorrect: " + segments[SEG_MODIFIER], e);
            }
            category = I18nConversionCategory.NUMBER;
            break;
          default:
            maxOffset = oldMaxOffset;
            throw new IllegalArgumentException("unknown format type: " + segments[SEG_TYPE]);
        }
      } else {
        category = I18nConversionCategory.GENERAL;
      }
      categories.add(category);
    }

    /**
     * Return the index of s in list. If not found, return the index of
     * s.trim().toLowerCase(Locale.ROOT) in list. If still not found, return -1.
     */
    private static final int findKeyword(String s, String[] list) {
      for (int i = 0; i < list.length; ++i) {
        if (s.equals(list[i])) {
          return i;
        }
      }

      // Try trimmed lowercase.
      @SuppressWarnings("interning:assignment") // test if value changed
      @InternedDistinct String ls = s.trim().toLowerCase(Locale.ROOT);
      if (ls != s) { // Don't loop if the string trim().toLowerCase returned the same object.
        for (int i = 0; i < list.length; ++i) {
          if (ls.equals(list[i])) {
            return i;
          }
        }
      }
      return -1;
    }
  }
}
