/*
 * Copyright 2007 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.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.user.rebind.AbstractSourceCreator;

import java.util.HashMap;
import java.util.Map;

/**
 * Links classes with their localized counterparts.
 */
class LocalizableLinkageCreator extends AbstractSourceCreator {
  
  static Map<String, JClassType> findDerivedClasses(TreeLogger logger,
      JClassType baseClass) throws UnableToCompleteException {
    // Construct valid set of candidates for this type.
    Map<String, JClassType> matchingClasses = new HashMap<String, JClassType>();
    // Add base class if possible.
    if (baseClass.isInterface() == null && baseClass.isAbstract() == false) {
      matchingClasses.put(ResourceFactory.DEFAULT_TOKEN, baseClass);
    }
    String baseName = baseClass.getSimpleSourceName();

    // Find matching sub types.
    JClassType[] x = baseClass.getSubtypes();
    for (int i = 0; i < x.length; i++) {
      JClassType subType = x[i];
      if ((subType.isInterface() == null) && (subType.isAbstract() == false)) {
        String name = subType.getSimpleSourceName();
        // Strip locale from type,
        int localeIndex = name.indexOf(ResourceFactory.LOCALE_SEPARATOR);
        String subTypeBaseName = name;
        if (localeIndex != -1) {
          subTypeBaseName = name.substring(0, localeIndex);
        }
        boolean matches = subTypeBaseName.equals(baseName);
        if (matches) {
          boolean isDefault = localeIndex == -1
              || localeIndex == name.length() - 1
              || ResourceFactory.DEFAULT_TOKEN.equals(name.substring(localeIndex + 1));
          if (isDefault) {
            // Don't override base as default if present.
            JClassType defaultClass = 
              matchingClasses.get(ResourceFactory.DEFAULT_TOKEN);
            if (defaultClass != null) {
              throw error(logger, defaultClass + " and " + baseName
                  + " are both potential default classes for " + baseClass);
            } else {
              matchingClasses.put(ResourceFactory.DEFAULT_TOKEN, subType);
            }
          } else {
            // Don't allow a locale to be ambiguous. Very similar to default
            // case, different error message.
            String localeSubString = name.substring(localeIndex + 1);
            JClassType dopClass = matchingClasses.get(localeSubString);
            if (dopClass != null) {
              throw error(logger, dopClass.getQualifiedSourceName() + " and "
                  + subType.getQualifiedSourceName()
                  + " are both potential matches to " + baseClass
                  + " in locale " + localeSubString);
            }
            matchingClasses.put(localeSubString, subType);
          }
        }
      }
    }
    return matchingClasses;
  }

  /**
   * Map to cache linkages of implementation classes and interfaces.
   */
  // Change back to ReferenceMap once apache collections is in.
  private final Map<String, String> implCache = new HashMap<String, String>();

  /**
   * * Finds associated implementation in the current locale. Here are the rules
   * <p>
   * </p>
   * <p>
   * If class name is X, and locale is z_y, look for X_z_y, then X_z, then X
   * </p>
   * 
   * @param baseClass
   * @return class name to link with
   * @throws UnableToCompleteException
   */
  String linkWithImplClass(TreeLogger logger, JClassType baseClass,
      String locale) throws UnableToCompleteException {

    String baseName = baseClass.getQualifiedSourceName();
    /**
     * Try to find implementation class, as the current class is not a Constant
     * or Message.
     */
    String className = implCache.get(baseName + locale);
    if (className != null) {
      return className;
    }

    if (baseClass.getName().indexOf(ResourceFactory.LOCALE_SEPARATOR) != -1) {
      throw error(logger, "Cannot have a " + ResourceFactory.LOCALE_SEPARATOR
          + " in the base localizable class " + baseClass);
    }
    Map<String, JClassType> matchingClasses =
      findDerivedClasses(logger, baseClass);
    // Now that we have all matches, find best class
    String localeSuffix = locale;
    JClassType result = null;  
    while (true) {
      // Check for current result.
      result = matchingClasses.get(localeSuffix);
      if (result != null) {
        break;
      }
      if (localeSuffix.equals(ResourceFactory.DEFAULT_TOKEN)) {
        // No classes matched.
        throw error(logger, "Cannot find a class to bind to argument type "
            + baseClass.getQualifiedSourceName());
      }
      
      localeSuffix = ResourceFactory.getParentLocaleName(localeSuffix);
    }
    implCache.put(baseName + locale, className);
    return result.getQualifiedSourceName();
  }
}
