/*
 * Copyright 2010 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.validation.rebind;

import com.google.gwt.core.ext.Generator;
import com.google.gwt.core.ext.GeneratorContext;
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.JParameterizedType;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.validation.client.GwtValidation;
import com.google.gwt.validation.client.impl.GwtSpecificValidator;

import javax.validation.Validator;

/**
 * Generates subclasses of {@link Validator} and {@link GwtSpecificValidator}. The generic
 * validator only handles the classes listed in the
 * {@link com.google.gwt.validation.client.GwtValidation} annotation. See
 * {@link com.google.gwt.validation.client.GwtValidation} for usage.
 */
public final class ValidatorGenerator extends Generator {

  private final BeanHelperCache cache;
  private Class<?>[] validGroups;

  // called by the compiler via reflection
  public ValidatorGenerator() {
    this.cache = new BeanHelperCache();
    this.validGroups = new Class<?>[]{ };
  }

  // called from tests
  public ValidatorGenerator(BeanHelperCache cache, Class<?>[] validGroups) {
    this.cache = cache;
    this.validGroups = validGroups;
  }

  @Override
  public String generate(TreeLogger logger, GeneratorContext context,
      String typeName) throws UnableToCompleteException {
    TypeOracle typeOracle = context.getTypeOracle();
    assert (typeOracle != null);

    JClassType validatorType = findType(logger, typeOracle, typeName);
    JClassType genericType = findType(logger, typeOracle, Validator.class.getName());
    JClassType gwtSpecificType =
        findType(logger, typeOracle, GwtSpecificValidator.class.getName());

    if (validatorType.isAssignableTo(genericType)) {
      return generateGenericValidator(logger, context, validatorType);
    } else if (validatorType.isAssignableTo(gwtSpecificType)) {
      return generateGwtSpecificValidator(logger, context, validatorType);
    } else {
      logger.log(TreeLogger.ERROR,
          "type is not a ValidatorGenerator or GwtSpecificValidatorGenerator: '" + typeName + "'",
          null);
      throw new UnableToCompleteException();
    }
  }

  private JClassType findType(TreeLogger logger, TypeOracle typeOracle, String typeName)
      throws UnableToCompleteException {
    JClassType result = typeOracle.findType(typeName);
    if (result == null) {
      logger.log(TreeLogger.ERROR, "Unable to find metadata for type '"
          + typeName + "'", null);
      throw new UnableToCompleteException();
    }
    return result;
  }

  private String generateGenericValidator(TreeLogger logger, GeneratorContext context,
      JClassType validatorType) throws UnableToCompleteException {
    String typeName = validatorType.getName();

    GwtValidation gwtValidation = validatorType.findAnnotationInTypeHierarchy(GwtValidation.class);

    if (gwtValidation == null) {
      logger.log(TreeLogger.ERROR, typeName + " must be anntotated with "
          + GwtValidation.class.getCanonicalName(), null);
      throw new UnableToCompleteException();
    }

    if (gwtValidation.value().length == 0) {
      logger.log(TreeLogger.ERROR,
          "The @" + GwtValidation.class.getSimpleName() + "  of " + typeName
              + "must specify at least one bean type to validate.", null);
      throw new UnableToCompleteException();
    }

    if (gwtValidation.groups().length == 0) {
      logger.log(TreeLogger.ERROR,
          "The @" + GwtValidation.class.getSimpleName() + "  of " + typeName
              + "must specify at least one validation group.", null);
      throw new UnableToCompleteException();
    }

    this.validGroups = gwtValidation.groups();

    TreeLogger validatorLogger = logger.branch(TreeLogger.DEBUG,
        "Generating Validator for  '" + validatorType.getQualifiedSourceName()
            + "'", null);
    AbstractCreator creator = new ValidatorCreator(validatorType,
        gwtValidation,
        validatorLogger,
        context, cache);
    return creator.create();
  }

  private String generateGwtSpecificValidator(TreeLogger logger, GeneratorContext context,
      JClassType validatorType) throws UnableToCompleteException {

    JClassType gwtSpecificInterface = getGwtSpecificValidator(logger, validatorType);
    JClassType beanType = getBeanType(logger, validatorType, gwtSpecificInterface);

    BeanHelper beanHelper = cache.createHelper(beanType, logger, context);

    if (beanHelper == null) {
      logger.log(TreeLogger.ERROR, "Unable to create BeanHelper for " + beanType
          + " " + GwtSpecificValidator.class.getSimpleName()
          + ".", null);
      throw new UnableToCompleteException();
    }

    AbstractCreator creator = new GwtSpecificValidatorCreator(validatorType,
        beanType, beanHelper, logger, context, cache, validGroups);
    return creator.create();
  }

  private JClassType getBeanType(TreeLogger logger, JClassType validator,
      JClassType gwtSpecificInterface) throws UnableToCompleteException {
    if (gwtSpecificInterface instanceof JParameterizedType) {
      JParameterizedType paramType = (JParameterizedType) gwtSpecificInterface;
      return paramType.getTypeArgs()[0];
    }
    logger.log(TreeLogger.ERROR, validator.getQualifiedSourceName()
        + " must implement " + GwtSpecificValidator.class.getCanonicalName()
        + " with a one generic parameter.", null);
    throw new UnableToCompleteException();
  }

  private JClassType getGwtSpecificValidator(TreeLogger logger,
      JClassType validator) throws UnableToCompleteException {
    for (JClassType interfaceType : validator.getImplementedInterfaces()) {
      if (interfaceType.getQualifiedSourceName().endsWith(
          GwtSpecificValidator.class.getCanonicalName())) {
        return interfaceType;
      }
    }
    logger.log(TreeLogger.ERROR, validator.getQualifiedSourceName()
        + " must implement " + GwtSpecificValidator.class.getCanonicalName(),
        null);
    throw new UnableToCompleteException();
  }
}
