/*
 * 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.client.GWT;
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.thirdparty.guava.common.collect.ImmutableList;
import com.google.gwt.thirdparty.guava.common.collect.Lists;
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter;
import com.google.gwt.validation.client.GwtValidation;
import com.google.gwt.validation.client.impl.AbstractGwtValidator;
import com.google.gwt.validation.client.impl.GwtBeanDescriptor;
import com.google.gwt.validation.client.impl.GwtSpecificValidator;
import com.google.gwt.validation.client.impl.GwtValidationContext;
import com.google.gwt.validation.client.impl.metadata.ValidationGroupsMetadata;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.GroupSequence;
import javax.validation.groups.Default;
import javax.validation.metadata.BeanDescriptor;

/**
 * Creates the validator for the given input class.
 */
public final class ValidatorCreator extends AbstractCreator {

  /**
   * The beans to validate in source declaration order.
   */
  private final ImmutableList<BeanHelper> beansToValidate;
  private final GwtValidation gwtValidation;

  public ValidatorCreator(JClassType validatorType, //
      GwtValidation gwtValidation, //
      TreeLogger logger, //
      GeneratorContext context,
      BeanHelperCache cache) throws UnableToCompleteException {
    super(context, logger, validatorType, cache);
    this.gwtValidation = gwtValidation;

    List<BeanHelper> temp = Lists.newArrayList();
    for (Class<?> clazz : gwtValidation.value()) {
      BeanHelper helper = createBeanHelper(clazz);
      temp.add(helper);
    }
    beansToValidate = Util.sortMostSpecificFirst(temp, BeanHelper.TO_CLAZZ);
  }

  @Override
  protected void compose(ClassSourceFileComposerFactory composerFactory) {
   addImports(composerFactory,
       GWT.class,
       GwtBeanDescriptor.class,
       GwtSpecificValidator.class,
       GwtValidationContext.class,
       ValidationGroupsMetadata.class,
       Set.class,
       HashSet.class,
       Map.class,
       HashMap.class,
       Default.class,
       ConstraintViolation.class,
       BeanDescriptor.class);
    composerFactory.setSuperclass(AbstractGwtValidator.class.getCanonicalName());
    composerFactory.addImplementedInterface(this.validatorType.getQualifiedSourceName());
  }

  @Override
  protected void writeClassBody(SourceWriter sourceWriter) {
    writeConstructor(sourceWriter);
    sourceWriter.println();
    writeCreateValidationGroupsMetadata(sourceWriter);
    sourceWriter.println();
    writeValidate(sourceWriter);
    sourceWriter.println();
    writeValidateProperty(sourceWriter);
    sourceWriter.println();
    writeValidateValue(sourceWriter);
    sourceWriter.println();
    writeGetConstraintsForClass(sourceWriter);
    sourceWriter.println();
    writeGwtValidate(sourceWriter);
  }

  private void writeConstructor(SourceWriter sw) {
    // public MyValidator() {
    sw.println("public " + getSimpleName() + "() {");
    sw.indent();

    // super(createValidationGroupsMetadata());
    sw.println("super(createValidationGroupsMetadata());");

    sw.outdent();
    sw.println("}");
  }

  private void writeContext(SourceWriter sw, BeanHelper bean, String objectName) {
    // GwtValidationContext<MyBean> context = new GwtValidationContext<MyBean>(
    sw.print(GwtValidationContext.class.getSimpleName());
    sw.print("<T> context = new ");
    sw.print(GwtValidationContext.class.getSimpleName());
    sw.println("<T>(");
    sw.indent();
    sw.indent();

    // (Class<T>) MyBean.class,
    sw.print("(Class<T>) ");
    sw.println(bean.getTypeCanonicalName() + ".class, ");

    // object,
    sw.println(objectName + ", ");

    // MyBeanValidator.INSTANCE.getConstraints(getValidationGroupsMetadata()),
    sw.print(bean.getFullyQualifiedValidatorName());
    sw.println(".INSTANCE.getConstraints(getValidationGroupsMetadata()), ");

    // getMessageInterpolator(),
    sw.println("getMessageInterpolator(), ");

    // getTraversableResolver(),
    sw.println("getTraversableResolver(), ");

    // this);
    sw.println("this);");
    sw.outdent();
    sw.outdent();
  }

  private void writeCreateValidationGroupsMetadata(SourceWriter sw) {
    // private static ValidationGroupsMetadata createValidationGroupsMetadata() {
    sw.println("private static ValidationGroupsMetadata createValidationGroupsMetadata() {");
    sw.indent();
    
    // return ValidationGroupsMetadata.builder()
    sw.println("return ValidationGroupsMetadata.builder()");
    sw.indent();
    sw.indent();
    for (Class<?> group : gwtValidation.groups()) {
      GroupSequence sequenceAnnotation = group.getAnnotation(GroupSequence.class);
      Class<?>[] groups;
      if (sequenceAnnotation != null) {
        // .addSequence(<<sequence>>
        sw.print(".addSequence(");
        sw.print(group.getCanonicalName() + ".class");
        groups = sequenceAnnotation.value();
      } else {
        // .addGroup(<<group>>
        sw.print(".addGroup(");
        sw.print(group.getCanonicalName() + ".class");
        groups = group.getInterfaces();
      }
      for (Class<?> clazz : groups) {
        // , <<group class>>
        sw.print(", ");
        sw.print(clazz.getCanonicalName() + ".class");
      }
      // )
      sw.println(")");
    }

    // .build();
    sw.println(".build();");
    sw.outdent();
    sw.outdent();

    // }
    sw.outdent();
    sw.println("}");
  }

  private void writeGetConstraintsForClass(SourceWriter sw) {
    // public BeanDescriptor getConstraintsForClass(Class<?> clazz {
    sw.println("public BeanDescriptor getConstraintsForClass(Class<?> clazz) {");
    sw.indent();

    // checkNotNull(clazz, "clazz");
    sw.println("checkNotNull(clazz, \"clazz\");");

    for (BeanHelper bean : beansToValidate) {
      writeGetConstraintsForClass(sw, bean);
    }

    writeThrowIllegalArgumnet(sw, "clazz.getName()");

    // }
    sw.outdent();
    sw.println("}");
  }

  private void writeGetConstraintsForClass(SourceWriter sw,
      BeanHelper bean) {
    // if (clazz.eqals(MyBean.class)) {
    sw.println("if (clazz.equals(" + bean.getTypeCanonicalName() + ".class)) {");
    sw.indent();

    // return MyBeanValidator.INSTANCE.getConstraints(getValidationGroupsMetadata());
    sw.print("return ");
    sw.print(bean.getFullyQualifiedValidatorName());
    sw.println(".INSTANCE.getConstraints(getValidationGroupsMetadata());");

    // }
    sw.outdent();
    sw.println("}");
  }

  private void writeGwtValidate(SourceWriter sw) {
    // public <T> Set<ConstraintViolation<T>> validate(GwtValidationContext<T>
    // context,
    sw.print("public <T> Set<ConstraintViolation<T>> ");
    sw.println("validate(GwtValidationContext<T> context,");
    sw.indent();
    sw.indent();

    // Object object, Class<?>... groups) {
    sw.println("Object object, Class<?>... groups) {");
    sw.outdent();

    sw.println("checkNotNull(context, \"context\");");
    sw.println("checkNotNull(object, \"object\");");
    sw.println("checkNotNull(groups, \"groups\");");
    sw.println("checkGroups(groups);");

    for (BeanHelper bean : cache.getAllBeans()) {
      writeGwtValidate(sw, bean);
    }

    // TODO(nchalko) log warning instead.
    writeThrowIllegalArgumnet(sw, "object.getClass().getName()");

    sw.outdent();
    sw.println("}");
  }

  private void writeGwtValidate(SourceWriter sw, BeanHelper bean) {
    writeIfInstanceofBeanType(sw, bean);
    sw.indent();

    // return PersonValidator.INSTANCE

    sw.print("return ");
    sw.println(bean.getFullyQualifiedValidatorName() + ".INSTANCE");
    sw.indent();
    sw.indent();
    // .validate(context, (<<MyBean>>) object, groups);
    sw.print(".validate(context, ");
    sw.print("(" + bean.getTypeCanonicalName() + ") object, ");
    sw.println("groups);");
    sw.outdent();
    sw.outdent();

    // }
    sw.outdent();
    sw.println("}");
  }

  private void writeIfInstanceofBeanType(SourceWriter sourceWriter, BeanHelper bean) {
    // if (object instanceof MyBean) {
    sourceWriter.print("if (object instanceof ");
    sourceWriter.print(bean.getTypeCanonicalName());
    sourceWriter.println(") {");
  }

  private void writeThrowIllegalArgumnet(SourceWriter sourceWriter,
      String getClassName) {
    // throw new IllegalArgumentException("MyValidator can not validate ",
    sourceWriter.print("throw new IllegalArgumentException(\"");
    sourceWriter.print(this.validatorType.getName() + " can not  validate \"");
    sourceWriter.indent();
    sourceWriter.indent();

    // + object.getClass().getName() +". "
    sourceWriter.print("+ ");
    sourceWriter.print(getClassName);
    sourceWriter.println("+ \". \"");

    // + "Valid values are {Foo.clas, Bar.class}
    sourceWriter.print("+ \"Valid types are ");
    sourceWriter.print(beansToValidate.toString());
    sourceWriter.println("\");");
    sourceWriter.outdent();
    sourceWriter.outdent();
  }

  private void writeValidate(SourceWriter sw) {
    // public <T> Set<ConstraintViolation<T>> validate(T object, Class<?>...
    // groups) {
    sw.println("public <T> Set<ConstraintViolation<T>> validate(T object, Class<?>... groups) {");
    sw.indent();

    sw.println("checkNotNull(object, \"object\");");
    sw.println("checkNotNull(groups, \"groups\");");
    sw.println("checkGroups(groups);");

    for (BeanHelper bean : beansToValidate) {
      writeValidate(sw, bean);
    }

    writeThrowIllegalArgumnet(sw, "object.getClass().getName()");

    sw.outdent();
    sw.println("}");
  }

  private void writeValidate(SourceWriter sw, BeanHelper bean) {
    writeIfInstanceofBeanType(sw, bean);
    sw.indent();

    writeContext(sw, bean, "object");

    // return PersonValidator.INSTANCE
    sw.print("return ");
    sw.println(bean.getFullyQualifiedValidatorName() + ".INSTANCE");
    sw.indent();
    sw.indent();

    // .validate(context, (<<MyBean>>) object, groups);
    sw.print(".validate(context, ");
    sw.print("(" + bean.getTypeCanonicalName() + ") object, ");
    sw.println("groups);");
    sw.outdent();
    sw.outdent();

    // }
    sw.outdent();
    sw.println("}");
  }

  private void writeValidateProperty(SourceWriter sw) {
    sw.println("public <T> Set<ConstraintViolation<T>> validateProperty(T object,String propertyName, Class<?>... groups) {");
    sw.indent();

    sw.println("checkNotNull(object, \"object\");");
    sw.println("checkNotNull(propertyName, \"propertyName\");");
    sw.println("checkNotNull(groups, \"groups\");");
    sw.println("checkGroups(groups);");

    for (BeanHelper bean : beansToValidate) {
      writeValidateProperty(sw, bean);
    }

    writeThrowIllegalArgumnet(sw, "object.getClass().getName()");

    sw.outdent();
    sw.println("}");
  }

  private void writeValidateProperty(SourceWriter sw, BeanHelper bean) {
    writeIfInstanceofBeanType(sw, bean);
    sw.indent();
    writeContext(sw, bean, "object");

    // return PersonValidator.INSTANCE
    sw.print("return ");
    sw.println(bean.getFullyQualifiedValidatorName() + ".INSTANCE");
    sw.indent();
    sw.indent();

    // .validateProperty(context, (MyBean) object, propertyName, groups);
    sw.print(".validateProperty(context, (");
    sw.print(bean.getTypeCanonicalName());
    sw.print(") object, propertyName, ");
    sw.println("groups);");
    sw.outdent();
    sw.outdent();

    // }
    sw.outdent();
    sw.println("}");
  }

  private void writeValidateValue(SourceWriter sw) {
    sw.println("public <T> Set<ConstraintViolation<T>> validateValue(Class<T> beanType, String propertyName, Object value, Class<?>... groups) {");
    sw.indent();

    sw.println("checkNotNull(beanType, \"beanType\");");
    sw.println("checkNotNull(propertyName, \"propertyName\");");
    sw.println("checkNotNull(groups, \"groups\");");
    sw.println("checkGroups(groups);");

    for (BeanHelper bean : beansToValidate) {
      writeValidateValue(sw, bean);
    }

    writeThrowIllegalArgumnet(sw, "beanType.getName()");

    sw.outdent();
    sw.println("}");
  }

  private void writeValidateValue(SourceWriter sw, BeanHelper bean) {
    sw.println("if (beanType.equals(" + bean.getTypeCanonicalName()
        + ".class)) {");
    sw.indent();
    writeContext(sw, bean, "null");

    // return PersonValidator.INSTANCE
    sw.print("return ");
    sw.println(bean.getFullyQualifiedValidatorName() + ".INSTANCE");
    sw.indent();
    sw.indent();

    // .validateValue(context, (Class<MyBean> beanType, propertyName, value,
    // groups);
    sw.print(".validateValue(context, (Class<");
    sw.print(bean.getTypeCanonicalName());
    sw.println(">)beanType, propertyName, value, groups);");
    sw.outdent();
    sw.outdent();

    // }
    sw.outdent();
    sw.println("}");
  }
}
