/*
 * 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 static com.google.gwt.i18n.rebind.AnnotationUtil.getClassAnnotation;

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.dev.resource.Resource;
import com.google.gwt.dev.util.collect.IdentityHashSet;
import com.google.gwt.i18n.client.LocalizableResource.DefaultLocale;
import com.google.gwt.i18n.rebind.AbstractResource.ResourceList;
import com.google.gwt.i18n.rebind.AnnotationsResource.AnnotationsError;
import com.google.gwt.i18n.shared.GwtLocale;
import com.google.gwt.i18n.shared.GwtLocaleFactory;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Creates resources.
 */
public abstract class ResourceFactory {

  /**
   * Pair of JClassType and GwtLocale.
   */
  private static class ClassLocale {

    private final JClassType clazz;
    private final GwtLocale locale;

    public ClassLocale(JClassType clazz, GwtLocale locale) {
      assert clazz != null;
      assert locale != null;
      this.clazz = clazz;
      this.locale = locale;
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj) {
        return true;
      }
      if (obj == null || getClass() != obj.getClass()) {
        return false;
      }
      ClassLocale other = (ClassLocale) obj;
      return clazz.equals(other.clazz) && locale.equals(other.locale);
    }

    public JClassType getJClass() {
      return clazz;
    }

    public GwtLocale getLocale() {
      return locale;
    }

    @Override
    public int hashCode() {
      return clazz.hashCode() + locale.hashCode() * 53;
    }

    @Override
    public String toString() {
      return clazz.getQualifiedSourceName() + "/" + locale.toString();
    }
  }

  /**
   * Separator between class name and locale in resource files. Should not
   * appear in valid localizable class names.
   */
  public static final char LOCALE_SEPARATOR = '_';

  private static Map<ClassLocale, ResourceList> cache = new HashMap<ClassLocale, ResourceList>();
  private static List<ResourceFactory> loaders = new ArrayList<ResourceFactory>();

  static {
    loaders.add(new LocalizedPropertiesResource.Factory());
  }

  /**
   * Clears the resource cache.
   */
  public static synchronized void clearCache() {
    cache.clear();
  }

  /**
   * 
   * @param logger
   * @param topClass
   * @param bundleLocale
   * @param isConstants
   * @param resourceMap a map of available {@link Resource Resources} by partial
   *          path; obtain this by calling
   *          {@link com.google.gwt.core.ext.GeneratorContext#getResourcesOracle()}.{@link com.google.gwt.dev.resource.ResourceOracle#getResourceMap() getResourceMap()}
   * @return resource list
   */
  public static synchronized ResourceList getBundle(TreeLogger logger,
      JClassType topClass, GwtLocale bundleLocale, boolean isConstants,
      Map<String, Resource> resourceMap) {
    List<GwtLocale> locales = bundleLocale.getCompleteSearchList();
    List<JClassType> classes = new ArrayList<JClassType>();
    Set<JClassType> seenClasses = new IdentityHashSet<JClassType>();
    Map<ClassLocale, AnnotationsResource> annotations = new HashMap<ClassLocale, AnnotationsResource>();
    GwtLocaleFactory factory = LocaleUtils.getLocaleFactory();
    GwtLocale defaultLocale = factory.getDefault();
    walkInheritanceTree(logger, topClass, factory, defaultLocale, classes,
        annotations, seenClasses, isConstants);
    // TODO(jat): handle explicit subinterface with other locales -- ie:
    // public interface Foo_es_MX extends Foo { ... }
    ResourceList allResources = new ResourceList();
    for (GwtLocale locale : locales) {
      for (JClassType clazz : classes) {
        ClassLocale key = new ClassLocale(clazz, locale);
        ResourceList resources;
        if (cache.containsKey(key)) {
          resources = cache.get(key);
        } else {
          cache.put(key, null);
          resources = new ResourceList();
          addFileResources(clazz, locale, resourceMap, resources);
          AnnotationsResource annotationsResource = annotations.get(key);
          if (annotationsResource != null) {
            resources.add(annotationsResource);
          }
          cache.put(key, resources);
        }
        if (resources != null) {
          allResources.addAll(resources);
        }
      }
    }
    String className = topClass.getQualifiedSourceName();
    TreeLogger branch = logger.branch(TreeLogger.SPAM,
        "Resource search order for " + className + ", locale " + bundleLocale);
    for (AbstractResource resource : allResources) {
      branch.log(TreeLogger.SPAM, resource.toString());
    }
    return allResources;
  }

  public static String getResourceName(JClassType targetClass) {
    String name = targetClass.getName();
    if (targetClass.isMemberType()) {
      name = name.replace('.', '$');
    }
    return name;
  }

  private static void addFileResources(JClassType clazz, GwtLocale locale,
      Map<String, Resource> resourceMap, ResourceList resources) {
    // TODO: handle classes in the default package?
    String targetPath = clazz.getPackage().getName() + '.'
        + getResourceName(clazz);
    String localizedPath = targetPath;
    if (!locale.isDefault()) {
      localizedPath = targetPath + LOCALE_SEPARATOR + locale.getAsString();
    }
    // Check for file-based resources.
    String partialPath = localizedPath.replace('.', '/');
    for (int i = 0; i < loaders.size(); i++) {
      ResourceFactory element = loaders.get(i);
      String ext = "." + element.getExt();
      String path = partialPath + ext;
      Resource resource = resourceMap.get(path);
      if (resource == null && partialPath.contains("$")) {
        // Also look for A_B for inner classes, as $ in path names
        // can cause issues for some build tools.
        path = partialPath.replace('$', '_') + ext;
        resource = resourceMap.get(path);
      }
      if (resource != null) {
        AbstractResource found = element.load(resource.openContents(), locale);
        found.setPath(path);
        resources.add(found);
      }
    }
  }

  private static void walkInheritanceTree(TreeLogger logger, JClassType clazz,
      GwtLocaleFactory factory, GwtLocale defaultLocale,
      List<JClassType> classes,
      Map<ClassLocale, AnnotationsResource> annotations,
      Set<JClassType> seenClasses, boolean isConstants) {
    if (seenClasses.contains(clazz)) {
      return;
    }
    seenClasses.add(clazz);
    classes.add(clazz);
    AnnotationsResource resource;
    try {
      resource = new AnnotationsResource(logger, clazz, defaultLocale,
          isConstants);
      if (resource.notEmpty()) {
        resource.setPath(clazz.getQualifiedSourceName());
        ClassLocale key = new ClassLocale(clazz, defaultLocale);
        annotations.put(key, resource);
        String defLocaleValue = null;

        // If the class has an embedded locale in it, use that for the default
        String className = clazz.getSimpleSourceName();
        int underscore = className.indexOf('_');
        if (underscore >= 0) {
          defLocaleValue = className.substring(underscore + 1);
        }

        // If there is an annotation declaring the default locale, use that
        DefaultLocale defLocaleAnnot = getClassAnnotation(clazz,
            DefaultLocale.class);
        if (defLocaleAnnot != null) {
          defLocaleValue = defLocaleAnnot.value();
        }
        GwtLocale defLocale = LocaleUtils.getLocaleFactory().fromString(
            defLocaleValue);
        if (!defLocale.isDefault()) {
          key = new ClassLocale(clazz, defLocale);
          annotations.put(key, resource);
        }
      }
    } catch (AnnotationsError e) {
      logger.log(TreeLogger.ERROR, e.getMessage(), e);
    }
    if (clazz.getSuperclass() != null) {
      walkInheritanceTree(logger, clazz.getSuperclass(), factory,
          defaultLocale, classes, annotations, seenClasses, isConstants);
    }
    for (JClassType intf : clazz.getImplementedInterfaces()) {
      walkInheritanceTree(logger, intf, factory, defaultLocale, classes,
          annotations, seenClasses, isConstants);
    }
  }

  abstract String getExt();

  abstract AbstractResource load(InputStream m, GwtLocale locale);
}
