/*
 * Copyright 2008 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.i18n.rebind;

import com.google.gwt.core.ext.Generator;
import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.PropertyOracle;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.NotFoundException;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.i18n.client.CurrencyList;
import com.google.gwt.i18n.client.impl.CurrencyDataImpl;
import com.google.gwt.i18n.shared.GwtLocale;
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter;

import org.apache.tapestry.util.text.LocalizedProperties;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.Map.Entry;
import java.util.regex.Pattern;

/**
 * Generator used to generate a localized version of CurrencyList, which
 * contains the list of currencies (with names, symbols, and other information)
 * localized to the current locale.
 */
public class CurrencyListGenerator extends Generator {

  /**
   * Immutable collection of data about a currency in a locale, built from the
   * CurrencyData and CurrencyExtra properties files.
   */
  private static class CurrencyInfo {

    private static final Pattern SPLIT_VERTICALBAR = Pattern.compile("\\|");

    private final String code;

    private final String displayName;

    private final int flags;

    private final boolean obsolete;

    private final String portableSymbol;

    private final String symbol;

    /**
     * Create an instance.
     * 
     * currencyData format:
     * 
     * <pre>
     *       display name|symbol|decimal digits|not-used-flag
     * </pre>
     * 
     * <ul>
     * <li>If a symbol is not supplied, the currency code will be used
     * <li>If # of decimal digits is omitted, 2 is used
     * <li>If a currency is not generally used, not-used-flag=1
     * <li>Trailing empty fields can be omitted
     * <li>If null, use currencyCode as the display name
     * </ul>
     * 
     * extraData format:
     * 
     * <pre>
     *       portable symbol|flags|currency symbol override
     *     flags are space separated list of:
     *       At most one of the following:
     *         SymPrefix     The currency symbol goes before the number,
     *                       regardless of the normal position for this locale.
     *         SymSuffix     The currency symbol goes after the number,
     *                       regardless of the normal position for this locale.
     *
     *       At most one of the following:
     *         ForceSpace    Always add a space between the currency symbol
     *                       and the number.
     *         ForceNoSpace  Never add a space between the currency symbol
     *                       and the number.
     * </pre>
     * 
     * @param currencyCode ISO4217 currency code
     * @param currencyData entry from a CurrencyData properties file
     * @param extraData entry from a CurrencyExtra properties file
     * @throws NumberFormatException
     */
    public CurrencyInfo(String currencyCode, String currencyData,
        String extraData) throws NumberFormatException {
      code = currencyCode;
      if (currencyData == null) {
        currencyData = currencyCode;
      }
      String[] currencySplit = SPLIT_VERTICALBAR.split(currencyData);
      String currencyDisplay = currencySplit[0];
      String currencySymbol = null;
      if (currencySplit.length > 1 && currencySplit[1].length() > 0) {
        currencySymbol = currencySplit[1];
      }
      int currencyFractionDigits = 2;
      if (currencySplit.length > 2 && currencySplit[2].length() > 0) {
        currencyFractionDigits = Integer.valueOf(currencySplit[2]);
      }
      boolean currencyObsolete = false;
      if (currencySplit.length > 3 && currencySplit[3].length() > 0) {
        currencyObsolete = Integer.valueOf(currencySplit[3]) != 0;
      }
      int currencyFlags = currencyFractionDigits;
      if (currencyObsolete) {
        currencyFlags |= CurrencyDataImpl.DEPRECATED_FLAG;
      }
      String currencyPortableSymbol = "";
      if (extraData != null) {
        // CurrencyExtra contains up to 3 fields separated by |
        // 0 - portable currency symbol
        // 1 - space-separated flags regarding currency symbol
        // positioning/spacing
        // 2 - override of CLDR-derived currency symbol
        String[] extraSplit = SPLIT_VERTICALBAR.split(extraData);
        currencyPortableSymbol = extraSplit[0];
        if (extraSplit.length > 1) {
          if (extraSplit[1].contains("SymPrefix")) {
            currencyFlags |= CurrencyDataImpl.POS_FIXED_FLAG;
          } else if (extraSplit[1].contains("SymSuffix")) {
            currencyFlags |= CurrencyDataImpl.POS_FIXED_FLAG
                | CurrencyDataImpl.POS_SUFFIX_FLAG;
          }
          if (extraSplit[1].contains("ForceSpace")) {
            currencyFlags |= CurrencyDataImpl.SPACING_FIXED_FLAG
                | CurrencyDataImpl.SPACE_FORCED_FLAG;
          } else if (extraSplit[1].contains("ForceNoSpace")) {
            currencyFlags |= CurrencyDataImpl.SPACING_FIXED_FLAG;
          }
        }
        // If a non-empty override is supplied, use it for the currency
        // symbol.
        if (extraSplit.length > 2 && extraSplit[2].length() > 0) {
          currencySymbol = extraSplit[2];
        }
        // If we don't have a currency symbol yet, use the portable symbol if
        // supplied.
        if (currencySymbol == null && currencyPortableSymbol.length() > 0) {
          currencySymbol = currencyPortableSymbol;
        }
      }
      // If all else fails, use the currency code as the symbol.
      if (currencySymbol == null) {
        currencySymbol = currencyCode;
      }
      displayName = currencyDisplay;
      symbol = currencySymbol;
      flags = currencyFlags;
      portableSymbol = currencyPortableSymbol;
      obsolete = currencyObsolete;
    }

    public String getDisplayName() {
      return displayName;
    }

    public int getFlags() {
      return flags;
    }

    public String getJson() {
      StringBuilder buf = new StringBuilder();
      buf.append("[ \"").append(quote(code)).append("\", \"");
      buf.append(quote(symbol)).append("\", ").append(flags);
      if (portableSymbol.length() > 0) {
        buf.append(", \"").append(quote(portableSymbol)).append('\"');
      }
      return buf.append(']').toString();
    }

    public String getSymbol() {
      return symbol;
    }

    public boolean isObsolete() {
      return obsolete;
    }
  }

  private static final String CURRENCY_DATA = CurrencyDataImpl.class.getCanonicalName();

  /**
   * Prefix for properties files containing CLDR-derived currency data for each
   * locale.
   */
  private static final String CURRENCY_DATA_PREFIX =
      "com/google/gwt/i18n/client/impl/cldr/CurrencyData";

  /**
   * Prefix for properties files containing additional flags about currencies
   * each locale, which are not present in CLDR.
   */
  private static final String CURRENCY_EXTRA_PREFIX =
      "com/google/gwt/i18n/client/constants/CurrencyExtra";

  private static final String CURRENCY_LIST = CurrencyList.class.getCanonicalName();

  /**
   * Prefix for properties files containing number formatting constants for each
   * locale. We use this only to get the default currency for our current
   * locale.
   */
  private static final String NUMBER_CONSTANTS_PREFIX =
      "com/google/gwt/i18n/client/constants/NumberConstantsImpl";

  /**
   * Backslash-escape any double quotes in the supplied string.
   * 
   * @param str string to quote
   * @return string with double quotes backslash-escaped.
   */
  private static String quote(String str) {
    return str.replace("\"", "\\\"");
  }

  /**
   * Generate an implementation for the given type.
   * 
   * @param logger error logger
   * @param context generator context
   * @param typeName target type name
   * @return generated class name
   * @throws UnableToCompleteException
   */
  @Override
  public final String generate(TreeLogger logger, GeneratorContext context,
      String typeName) throws UnableToCompleteException {
    assert CURRENCY_LIST.equals(typeName);
    TypeOracle typeOracle = context.getTypeOracle();

    PropertyOracle propertyOracle = context.getPropertyOracle();
    LocaleUtils localeUtils = LocaleUtils.getInstance(logger, propertyOracle);
    GwtLocale locale = localeUtils.getCompileLocale();
    Set<GwtLocale> runtimeLocales = localeUtils.getRuntimeLocales();

    JClassType targetClass;
    try {
      targetClass = typeOracle.getType(typeName);
    } catch (NotFoundException e) {
      logger.log(TreeLogger.ERROR, "No such type", e);
      throw new UnableToCompleteException();
    }
    if (runtimeLocales.isEmpty()) {
      return generateLocaleTree(logger, context, targetClass, locale);
    }
    CachedGeneratorContext cachedContext = new CachedGeneratorContext(context);
    return generateRuntimeSelection(logger, cachedContext, targetClass, locale,
        runtimeLocales);
  }

  /**
   * Generate an implementation class for the requested locale, including all
   * parent classes along the inheritance chain. The data will be kept at the
   * location in the inheritance chain where it was defined in properties files.
   * 
   * @param logger
   * @param context
   * @param targetClass
   * @param locale
   * @return generated class name for the requested locale
   */
  private String generateLocaleTree(TreeLogger logger, GeneratorContext context,
      JClassType targetClass, GwtLocale locale) {
    String superClassName = CURRENCY_LIST;
    List<GwtLocale> searchList = locale.getCompleteSearchList();

    /**
     * Map of currency code -> CurrencyInfo for that code.
     */
    Map<String, CurrencyInfo> allCurrencyData = new HashMap<String, CurrencyInfo>();

    LocalizedProperties currencyExtra = null;
    /*
     * The searchList is guaranteed to be ordered such that subclasses always
     * precede superclasses. Therefore, we iterate backwards to ensure that
     * superclasses are always generated first.
     */
    String lastDefaultCurrencyCode = null;
    for (int i = searchList.size(); i-- > 0;) {
      GwtLocale search = searchList.get(i);
      LocalizedProperties newExtra = getProperties(CURRENCY_EXTRA_PREFIX,
          search);
      if (newExtra != null) {
        currencyExtra = newExtra;
      }
      Map<String, String> currencyData = getCurrencyData(search);
      Set<String> keySet = currencyData.keySet();
      String[] currencies = new String[keySet.size()];
      keySet.toArray(currencies);
      Arrays.sort(currencies);

      // Go ahead and populate the data map.
      for (String currencyCode : currencies) {
        String extraData = currencyExtra == null ? null
            : currencyExtra.getProperty(currencyCode);
        allCurrencyData.put(currencyCode, new CurrencyInfo(currencyCode,
            currencyData.get(currencyCode), extraData));
      }

      String defCurrencyCode = getDefaultCurrency(search);
      // If this locale specifies a particular locale, or the one that is
      // inherited has been changed in this locale, re-specify the default
      // currency so the method will be generated.
      if (defCurrencyCode == null && keySet.contains(lastDefaultCurrencyCode)) {
        defCurrencyCode = lastDefaultCurrencyCode;
      }
      if (!currencyData.isEmpty() || defCurrencyCode != null) {
        String newClass =
            generateOneLocale(logger, context, targetClass, search,
                superClassName, currencies, allCurrencyData, defCurrencyCode);
        superClassName = newClass;
        lastDefaultCurrencyCode = defCurrencyCode;
      }
    }
    return superClassName;
  }

  /**
   * Generate the implementation for a single locale, overriding from its parent
   * only data that has changed in this locale.
   * 
   * @param logger
   * @param context
   * @param targetClass
   * @param locale
   * @param superClassName
   * @param currencies the set of currencies defined in this locale
   * @param allCurrencyData map of currency code -> unparsed CurrencyInfo for
   *        that code
   * @param defCurrencyCode default currency code for this locale
   * @return fully-qualified class name generated
   */
  private String generateOneLocale(TreeLogger logger, GeneratorContext context,
      JClassType targetClass, GwtLocale locale, String superClassName,
      String[] currencies, Map<String, CurrencyInfo> allCurrencyData,
      String defCurrencyCode) {
    String packageName = targetClass.getPackage().getName();
    String className = targetClass.getName().replace('.', '_') + "_"
        + locale.getAsString();
    PrintWriter pw = context.tryCreate(logger, packageName, className);
    if (pw != null) {
      ClassSourceFileComposerFactory factory =
          new ClassSourceFileComposerFactory(packageName, className);
      factory.setSuperclass(superClassName);
      factory.addImport(CURRENCY_LIST);
      factory.addImport(CURRENCY_DATA);
      SourceWriter writer = factory.createSourceWriter(context, pw);
      if (currencies.length > 0) {
        writeCurrencyMethod(className, writer, currencies, allCurrencyData);
        writeNamesMethod(className, writer, currencies, allCurrencyData);
      }
      if (defCurrencyCode != null) {
        CurrencyInfo currencyInfo = allCurrencyData.get(defCurrencyCode);
        if (currencyInfo == null) {
          // Synthesize a null info if the specified default wasn't found.
          currencyInfo = new CurrencyInfo(defCurrencyCode, null, null);
          allCurrencyData.put(defCurrencyCode, currencyInfo);
        }
        writer.println();
        writer.println("@Override");
        writer.println("public native CurrencyData getDefault() /*-{");
        writer.println("  return " + currencyInfo.getJson() + ";");
        writer.println("}-*/;");
      }
      writer.commit(logger);
    }
    return packageName + "." + className;
  }

  /**
   * Generate a class which can select between alternate implementations at
   * runtime based on the runtime locale.
   * 
   * @param logger TreeLogger instance for log messages
   * @param context GeneratorContext for generating source files
   * @param targetClass class to generate
   * @param compileLocale the compile-time locale we are generating for
   * @param locales set of all locales to generate
   * @return fully-qualified class name that was generated
   */
  private String generateRuntimeSelection(TreeLogger logger,
      GeneratorContext context, JClassType targetClass, GwtLocale compileLocale,
      Set<GwtLocale> locales) {
    String packageName = targetClass.getPackage().getName();
    String className =
        targetClass.getName().replace('.', '_') + "_"
            + compileLocale.getAsString() + "_runtimeSelection";
    PrintWriter pw = context.tryCreate(logger, packageName, className);
    if (pw != null) {
      ClassSourceFileComposerFactory factory =
          new ClassSourceFileComposerFactory(packageName, className);
      factory.setSuperclass(targetClass.getQualifiedSourceName());
      factory.addImport(CURRENCY_LIST);
      factory.addImport(CURRENCY_DATA);
      factory.addImport("com.google.gwt.i18n.client.LocaleInfo");
      SourceWriter writer = factory.createSourceWriter(context, pw);
      writer.println("private CurrencyList instance;");
      writer.println();
      writer.println("@Override");
      writer.println("public CurrencyData getDefault() {");
      writer.println("  ensureInstance();");
      writer.println("  return instance.getDefault();");
      writer.println("}");
      writer.println();
      writer.println("@Override");
      writer.println("protected void loadCurrencyMap() {");
      writer.println("  ensureInstance();");
      writer.println("  instance.loadCurrencyMap();");
      writer.println("  dataMap = instance.dataMap;");
      writer.println("}");
      writer.println();
      writer.println("@Override");
      writer.println("protected void loadNamesMap() {");
      writer.println("  ensureInstance();");
      writer.println("  instance.loadNamesMap();");
      writer.println("  namesMap = instance.namesMap;");
      writer.println("}");
      writer.println();
      writer.println("private void ensureInstance() {");
      writer.indent();
      writer.println("if (instance != null) {");
      writer.println("  return;");
      writer.println("}");
      boolean fetchedLocale = false;
      Map<String, Set<GwtLocale>> localeMap = new TreeMap<String,
          Set<GwtLocale>>();
      String compileLocaleClass =
          processChildLocale(logger, context, targetClass, localeMap,
              compileLocale);
      if (compileLocaleClass == null) {
        // already gave warning, just use default implementation
        return null;
      }
      for (GwtLocale runtimeLocale : locales) {
        processChildLocale(logger, context, targetClass, localeMap,
            runtimeLocale);
      }
      for (Entry<String, Set<GwtLocale>> entry : localeMap.entrySet()) {
        if (!fetchedLocale) {
          writer.println("String runtimeLocale = LocaleInfo.getCurrentLocale().getLocaleName();");
          fetchedLocale = true;
        }
        boolean firstLocale = true;
        String generatedClass = entry.getKey();
        if (compileLocaleClass.equals(generatedClass)) {
          // The catch-all will handle this
          continue;
        }
        writer.print("if (");
        for (GwtLocale locale : entry.getValue()) {
          if (firstLocale) {
            firstLocale = false;
          } else {
            writer.println();
            writer.print("    || ");
          }
          writer.print("\"" + locale.toString() + "\".equals(runtimeLocale)");
        }
        writer.println(") {");
        writer.println("  instance = new " + generatedClass + "();");
        writer.println("  return;");
        writer.println("}");
      }
      writer.println("instance = new " + compileLocaleClass + "();");
      writer.outdent();
      writer.println("}");
      writer.commit(logger);
    }
    return packageName + "." + className;
  }

  /**
   * Return a map of currency data for the requested locale, or null if there is
   * not one (not that inheritance is not handled here).
   * <p/>
   * The keys are ISO4217 currency codes. The format of the map values is:
   * 
   * <pre>
   * display name|symbol|decimal digits|not-used-flag
   * </pre>
   * 
   * If a symbol is not supplied, the currency code will be used If # of decimal
   * digits is omitted, 2 is used If a currency is not generally used,
   * not-used-flag=1 Trailing empty fields can be omitted
   * 
   * @param locale
   * @return currency data map
   */
  @SuppressWarnings("unchecked")
  private Map<String, String> getCurrencyData(GwtLocale locale) {
    LocalizedProperties currencyData = getProperties(CURRENCY_DATA_PREFIX,
        locale);
    if (currencyData == null) {
      return Collections.emptyMap();
    }
    return currencyData.getPropertyMap();
  }

  /**
   * Returns the default currency code for the requested locale.
   * 
   * @param locale
   * @return ISO4217 currency code
   */
  private String getDefaultCurrency(GwtLocale locale) {
    String defCurrencyCode = null;
    LocalizedProperties numberConstants = getProperties(NUMBER_CONSTANTS_PREFIX, locale);
    if (numberConstants != null) {
      defCurrencyCode = numberConstants.getProperty("defCurrencyCode");
    }
    if (defCurrencyCode == null && locale.isDefault()) {
      defCurrencyCode = "USD";
    }
    return defCurrencyCode;
  }

  /**
   * Load a properties file for a given locale. Note that locale inheritance is
   * the responsibility of the caller.
   * 
   * @param prefix classpath prefix of properties file
   * @param locale locale to load
   * @return LocalizedProperties instance containing properties file or null if
   *         not found.
   */
  private LocalizedProperties getProperties(String prefix, GwtLocale locale) {
    String propFile = prefix;
    if (!locale.isDefault()) {
      propFile += "_" + locale.getAsString();
    }
    propFile += ".properties";
    InputStream str = null;
    ClassLoader classLoader = getClass().getClassLoader();
    LocalizedProperties props = new LocalizedProperties();
    try {
      str = classLoader.getResourceAsStream(propFile);
      if (str != null) {
        props.load(str, "UTF-8");
        return props;
      }
    } catch (UnsupportedEncodingException e) {
      // UTF-8 should always be defined
      return null;
    } catch (IOException e) {
      return null;
    } finally {
      if (str != null) {
        try {
          str.close();
        } catch (IOException e) {
        }
      }
    }
    return null;
  }

  /**
   * Generate an implementation for a runtime locale, to be referenced from the
   * generated runtime selection code.
   * 
   * @param logger
   * @param context
   * @param targetClass
   * @param localeMap
   * @param locale
   * @return class name of the generated class, or null if failed
   */
  private String processChildLocale(TreeLogger logger, GeneratorContext context,
      JClassType targetClass, Map<String, Set<GwtLocale>> localeMap,
      GwtLocale locale) {
    String generatedClass = generateLocaleTree(logger, context, targetClass,
        locale);
    if (generatedClass == null) {
      logger.log(TreeLogger.ERROR, "Failed to generate "
          + targetClass.getQualifiedSourceName() + " in locale "
          + locale.toString());
      // skip failed locale
      return null;
    }
    Set<GwtLocale> locales = localeMap.get(generatedClass);
    if (locales == null) {
      locales = new HashSet<GwtLocale>();
      localeMap.put(generatedClass, locales);
    }
    locales.add(locale);
    return generatedClass;
  }

  /**
   * Writes a loadCurrencyMap method for the current locale, based on its
   * currency data and its superclass (if any). As currencies are included in
   * this method, their names are added to {@code nameMap} for later use.
   * 
   * If no new currency data is added for this locale over its superclass, the
   * method is omitted entirely.
   * 
   * @param allCurrencyData map of currency codes to currency data for the
   *        current locale, including all inherited currencies data
   * @param className name of the class we are generating
   * @param writer SourceWriter instance to use for writing the class
   * @param currencies array of valid currency names in the order they should be
   *        listed
   */
  private void writeCurrencyMethod(String className, SourceWriter writer,
      String[] currencies, Map<String, CurrencyInfo> allCurrencyData) {
    boolean needHeader = true;
    for (String currencyCode : currencies) {
      CurrencyInfo currencyInfo = allCurrencyData.get(currencyCode);
      if (needHeader) {
        needHeader = false;
        writer.println();
        writer.println("private void loadSuperCurrencyMap() {");
        writer.println("  super.loadCurrencyMap();");
        writer.println("}");
        writer.println();
        writer.println("@Override");
        writer.println("protected native void loadCurrencyMap() /*-{");
        writer.indent();
        writer.println("this.@com.google.gwt.i18n.client." + className
            + "::loadSuperCurrencyMap()();");
        writer.println("this.@com.google.gwt.i18n.client." + className
            + "::overrideCurrencyMap(Lcom/google/gwt/core/client/"
            + "JavaScriptObject;)({");
        writer.indent();
      }
      writer.println("// " + currencyInfo.getDisplayName());
      writer.println("\"" + quote(currencyCode) + "\": "
          + currencyInfo.getJson() + ",");
    }
    if (!needHeader) {
      writer.outdent();
      writer.println("});");
      writer.outdent();
      writer.println("}-*/;");
    }
  }

  /**
   * Writes a loadNamesMap method for the current locale, based on its the
   * supplied names map and its superclass (if any).
   * 
   * If no new names are added for this locale over its superclass, the method
   * is omitted entirely.
   * 
   * @param className name of the class we are generating
   * @param writer SourceWriter instance to use for writing the class
   * @param currencies array of valid currency names in the order they should be
   *        listed
   */
  private void writeNamesMethod(String className, SourceWriter writer,
      String[] currencies, Map<String, CurrencyInfo> allCurrencyData) {
    boolean needHeader = true;
    for (String currencyCode : currencies) {
      CurrencyInfo currencyInfo = allCurrencyData.get(currencyCode);
      String displayName = currencyInfo.getDisplayName();
      if (displayName != null && !currencyCode.equals(displayName)) {
        if (needHeader) {
          needHeader = false;
          writer.println();
          writer.println("private void loadSuperNamesMap() {");
          writer.println("  super.loadNamesMap();");
          writer.println("}");
          writer.println();
          writer.println("@Override");
          writer.println("protected native void loadNamesMap() /*-{");
          writer.indent();
          writer.println("this.@com.google.gwt.i18n.client." + className
              + "::loadSuperNamesMap()();");
          writer.println("this.@com.google.gwt.i18n.client." + className
              + "::overrideNamesMap(Lcom/google/gwt/core/"
              + "client/JavaScriptObject;)({");
          writer.indent();
        }
        writer.println("\"" + quote(currencyCode) + "\": \""
            + quote(displayName) + "\",");
      }
    }
    if (!needHeader) {
      writer.outdent();
      writer.println("});");
      writer.outdent();
      writer.println("}-*/;");
    }
  }
}
