/*
 * 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.TreeLogger;
import com.google.gwt.core.ext.typeinfo.JMethod;
import com.google.gwt.i18n.rebind.AbstractResource.MissingResourceException;
import com.google.gwt.i18n.rebind.AbstractResource.ResourceList;
import com.google.gwt.i18n.shared.GwtLocale;
import com.google.gwt.user.rebind.AbstractGeneratorClassCreator;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;

/**
 * Creator for methods of the form Map getX() .
 */
class ConstantsMapMethodCreator extends AbstractLocalizableMethodCreator {

  static final String GENERIC_STRING_MAP_TYPE = "java.util.Map<java.lang.String, java.lang.String>";

  /**
   * Constructor for localizable returnType method creator.
   *
   * @param classCreator
   */
  public ConstantsMapMethodCreator(AbstractGeneratorClassCreator classCreator) {
    super(classCreator);
  }

  /**
   * Generates Map of key/value pairs for a list of keys.
   *
   * @param logger TreeLogger instance for logging
   * @param method method body to create
   * @param mapName name to create map from
   * @param resourceList AbstractResource for key lookup
   * @param locale locale to use for localized string lookup
   */
  @Override
  public void createMethodFor(TreeLogger logger, JMethod method,
      String mapName, ResourceList resourceList, GwtLocale locale) {
    String methodName = method.getName();
    if (method.getParameters().length > 0) {
      error(
          logger,
          methodName
              + " cannot have parameters; extend Messages instead if you need to create "
              + "parameterized messages");
    }
    // make sure cache exists
    enableCache();
    // check cache for array
    println(GENERIC_STRING_MAP_TYPE + " args = (" + GENERIC_STRING_MAP_TYPE
        + ") cache.get(" + wrap(methodName) + ");");
    // if not found create Map
    println("if (args == null) {");
    indent();
    println("args = new java.util.HashMap<String, String>();");

    String keyString;
    try {
      keyString = resourceList.getRequiredString(mapName);
    } catch (MissingResourceException e) {
      e.setDuring("getting key list");
      throw e;
    }

    String[] keys = ConstantsStringArrayMethodCreator.split(keyString);
    ResourceList resources = getResources();
    // Use a LinkedHashMap to preserve declaration order (but remove dups).
    Map<String, String> map = new LinkedHashMap<String, String>();
    for (String key : keys) {
      if (key.length() == 0) {
        continue;
      }

      try {
        // check for "map[key]=value" first
        String value = resources.getStringExt(mapName, key);
        if (value == null) {
          // for backwards compatibility, check for "key=value", which must be
          // present if the form above isn't present.
          value = resources.getRequiredString(key);
        }
        map.put(key, value);
      } catch (MissingResourceException e) {
        e.setDuring("implementing map");
        throw e;
      }
    }

    for (Entry<String, String> entry : map.entrySet()) {
      println("args.put(" + wrap(entry.getKey()) + ", " + wrap(entry.getValue()) + ");");
    }
    println("args = java.util.Collections.unmodifiableMap(args);");
    println("cache.put(" + wrap(methodName) + ", args);");
    outdent();
    println("}");
    println("return args;");
  }
}
