/*
 * 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.JMethod;
import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.core.ext.typeinfo.NotFoundException;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.i18n.client.CustomDateTimeFormat;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.i18n.client.CustomDateTimeFormat.Pattern;
import com.google.gwt.i18n.shared.GwtLocale;
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter;

import java.io.PrintWriter;

/**
 * Generator used to generate an implementation of a
 * {@link CustomDateTimeFormat} interface, computing the best matching localized
 * format patterns at compile time.
 */
public class CustomDateTimeFormatGenerator extends Generator {

  /**
   * 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, final GeneratorContext context,
      String typeName) throws UnableToCompleteException {
    TypeOracle typeOracle = context.getTypeOracle();
    // Get the current locale and interface type.
    PropertyOracle propertyOracle = context.getPropertyOracle();
    LocaleUtils localeUtils = LocaleUtils.getInstance(logger, propertyOracle,
        context);

    JClassType targetClass;
    try {
      targetClass = typeOracle.getType(typeName);
    } catch (NotFoundException e) {
      logger.log(TreeLogger.ERROR, "No such type " + typeName, e);
      throw new UnableToCompleteException();
    }
    JClassType cdtfClass;
    try {
      cdtfClass = typeOracle.getType(CustomDateTimeFormat.class.getName());
    } catch (NotFoundException e) {
      logger.log(TreeLogger.ERROR, "No such type "
          + CustomDateTimeFormat.class.getName(), e);
      throw new UnableToCompleteException();
    }
    if (!cdtfClass.isAssignableFrom(targetClass)) {
      logger.log(TreeLogger.ERROR, typeName + " is not assignable to "
          + CustomDateTimeFormat.class.getName());
      throw new UnableToCompleteException();
    }
    JClassType dateTimeFormat;
    try {
      dateTimeFormat = typeOracle.getType(DateTimeFormat.class.getName());
    } catch (NotFoundException e) {
      logger.log(TreeLogger.ERROR, "No DateTimeFormat type?", e);
      throw new UnableToCompleteException();
    }
    // TODO(jat): runtime locales support
    GwtLocale gwtLocale = localeUtils.getCompileLocale();
    DateTimePatternGenerator dtpg = new DateTimePatternGenerator(gwtLocale);
    String packageName = targetClass.getPackage().getName();
    String className = targetClass.getName().replace('.', '_') + "_"
        + gwtLocale.getAsString();
    PrintWriter pw = context.tryCreate(logger, packageName, className);
    if (pw != null) {
      ClassSourceFileComposerFactory factory = new ClassSourceFileComposerFactory(
          packageName, className);
      factory.addImplementedInterface(targetClass.getQualifiedSourceName());
      factory.addImport("com.google.gwt.i18n.client.DateTimeFormat");
      SourceWriter writer = factory.createSourceWriter(context, pw);
      writer.indent();
      for (JMethod method : targetClass.getMethods()) {
        JType returnType = method.getReturnType();
        if (returnType != dateTimeFormat) {
          logger.log(TreeLogger.ERROR, typeName + "." + method.getName()
              + " must return DateTimeFormat");
          throw new UnableToCompleteException();
        }
        Pattern annotation = method.getAnnotation(Pattern.class);
        if (annotation == null) {
          logger.log(TreeLogger.ERROR, typeName + "." + method.getName()
              + " must have an @Pattern annotation");
          throw new UnableToCompleteException();
        }
        String pattern = annotation.value();
        pattern = dtpg.getBestPattern(pattern); 
        writer.println();
        writer.println("public "
            + method.getReturnType().getQualifiedSourceName() + " "
            + method.getName() + "() {");
        writer.println("  return DateTimeFormat.getFormat(\"" + pattern
            + "\");");
        writer.println("}");
      }
      writer.commit(logger);
    }
    return packageName + "." + className;
  }
}
