/*
 * 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.client;

import com.google.gwt.core.client.GWT;

import java.util.List;

import javax.validation.Configuration;
import javax.validation.ValidationException;
import javax.validation.ValidationProviderResolver;
import javax.validation.ValidatorFactory;
import javax.validation.bootstrap.GenericBootstrap;
import javax.validation.bootstrap.ProviderSpecificBootstrap;
import javax.validation.spi.BootstrapState;
import javax.validation.spi.ValidationProvider;

/**
 * This class is the entry point for Bean Validation. There are three ways to
 * bootstrap it:
 * <ul>
 * <li>
 * The easiest approach is to build the default <code>ValidatorFactory</code>.
 *
 * <pre>{@code ValidatorFactory factory = Validation.buildDefaultValidatorFactory();}</pre>
 * In this case, the default validation provider resolver will be used to locate
 * available providers. The chosen provider is defined as followed:
 * <ul>
 * <li>Since GWT does not support XML configuration, the first provider returned
 * by the <code>ValidationProviderResolver</code> instance is used.</li>
 * </ul>
 * </li>
 * <li>
 * The second bootstrap approach allows to choose a custom
 * <code>ValidationProviderResolver</code>. The chosen
 * <code>ValidationProvider</code> is then determined in the same way as in the
 * default bootstrapping case (see above).
 *
 * <pre>{@code
 * Configuration<?> configuration = Validation
 *    .byDefaultProvider()
 *    .providerResolver( new MyResolverStrategy() )
 *    .configure();
 * ValidatorFactory factory = configuration.buildValidatorFactory();}
 * </pre>
 * </li>
 * <li>
 * The third approach allows you to specify explicitly and in a type safe
 * fashion the expected provider.
 * <p/>
 * Optionally you can choose a custom <code>ValidationProviderResolver</code>.
 *
 * <pre>{@code
 * ACMEConfiguration configuration = Validation
 *    .byProvider(ACMEProvider.class)
 *    .providerResolver( new MyResolverStrategy() )  // optionally set the provider resolver
 *    .configure();
 * ValidatorFactory factory = configuration.buildValidatorFactory();}
 * </pre>
 * </li>
 * </ul>
 * Note:<br/>
 * <ul>
 * <li>
 * The <code>ValidatorFactory</code> object built by the bootstrap process
 * should be cached and shared amongst <code>Validator</code> consumers.</li>
 * <li>
 * This class is thread-safe.</li>
 * </ul>
 *
 * This class was modified by Google from the original
 * javax.validation.Validation source to make it suitable for GWT.
 */
public class Validation {

  // private class, not exposed
  private static class GenericBootstrapImpl implements GenericBootstrap,
      BootstrapState {

    private ValidationProviderResolver defaultResolver;
    private ValidationProviderResolver resolver;

    public Configuration<?> configure() {
      ValidationProviderResolver aResolver = this.resolver == null
          ? getDefaultValidationProviderResolver() : this.resolver;

      List<ValidationProvider<?>> resolvers;
      try {
        resolvers = aResolver.getValidationProviders();
      } catch (RuntimeException re) {
        throw new ValidationException(
            "Unable to get available provider resolvers.", re);
      }

      if (resolvers.size() == 0) {
        // FIXME looks like an assertion error almost
        throw new ValidationException("Unable to find a default provider");
      }

      Configuration<?> config;
      try {
        config = aResolver.getValidationProviders().get(0).createGenericConfiguration(
            this);
      } catch (RuntimeException re) {
        throw new ValidationException("Unable to instantiate Configuration.",
            re);
      }

      return config;
    }

    public ValidationProviderResolver getDefaultValidationProviderResolver() {
      if (defaultResolver == null) {
        defaultResolver = GWT.create(ValidationProviderResolver.class);
      }
      return defaultResolver;
    }

    public ValidationProviderResolver getValidationProviderResolver() {
      return resolver;
    }

    public GenericBootstrap providerResolver(ValidationProviderResolver resolver) {
      this.resolver = resolver;
      return this;
    }
  }

  // private class, not exposed
  private static class ProviderSpecificBootstrapImpl
      <T extends Configuration<T>, U extends ValidationProvider<T>>
      implements ProviderSpecificBootstrap<T> {

    private ValidationProviderResolver resolver;
    private final Class<U> validationProviderClass;

    public ProviderSpecificBootstrapImpl(Class<U> validationProviderClass) {
      this.validationProviderClass = validationProviderClass;
    }

    /**
     * Determine the provider implementation suitable for byProvider(Class) and
     * delegate the creation of this specific Configuration subclass to the
     * provider.
     *
     * @return a Configuration sub interface implementation
     */
    public T configure() {
      if (validationProviderClass == null) {
        throw new ValidationException(
            "builder is mandatory. Use Validation.byDefaultProvider() to use the generic provider discovery mechanism");
      }
      // used mostly as a BootstrapState
      GenericBootstrapImpl state = new GenericBootstrapImpl();
      if (resolver == null) {
        resolver = state.getDefaultValidationProviderResolver();
      } else {
        // stay null if no resolver is defined
        state.providerResolver(resolver);
      }

      List<ValidationProvider<?>> resolvers;
      try {
        resolvers = resolver.getValidationProviders();
      } catch (RuntimeException re) {
        throw new ValidationException(
            "Unable to get available provider resolvers.", re);
      }

      for (ValidationProvider<?> provider : resolvers) {
        // GWT validation only support exact matches.
        if (validationProviderClass.equals(provider.getClass())) {
          @SuppressWarnings("unchecked")
          ValidationProvider<T> specificProvider = (ValidationProvider<T>) provider;
          return specificProvider.createSpecializedConfiguration(state);
        }
      }
      throw new ValidationException("Unable to find provider: "
          + validationProviderClass);
    }

    /**
     * Optionally define the provider resolver implementation used. If not
     * defined, use the default ValidationProviderResolver
     *
     * @param resolver ValidationProviderResolver implementation used
     *
     * @return self
     */
    public ProviderSpecificBootstrap<T> providerResolver(
        ValidationProviderResolver resolver) {
      this.resolver = resolver;
      return this;
    }
  }

  /**
   * Build and return a <code>ValidatorFactory</code> instance based on the
   * default Bean Validation provider.
   * <p/>
   * The provider list is resolved using the default validation provider
   * resolver logic.
   * <p/>
   * The code is semantically equivalent to
   * <code>Validation.byDefaultProvider().configure().buildValidatorFactory()</code>
   * 
   * @return <code>ValidatorFactory</code> instance.
   * 
   * @throws ValidationException if the ValidatorFactory cannot be built
   */
  public static ValidatorFactory buildDefaultValidatorFactory() {
    return byDefaultProvider().configure().buildValidatorFactory();
  }

  /**
   * Build a <code>Configuration</code>. The provider list is resolved using the
   * strategy provided to the bootstrap state.
   *
   * <pre>
   * Configuration&lt?&gt; configuration = Validation
   *    .byDefaultProvider()
   *    .providerResolver( new MyResolverStrategy() )
   *    .configure();
   * ValidatorFactory factory = configuration.buildValidatorFactory();
   * </pre>
   *
   * The first available provider will be returned.
   *
   * @return instance building a generic <code>Configuration</code> complaint
   *         with the bootstrap state provided.
   */
  public static GenericBootstrap byDefaultProvider() {
    return new GenericBootstrapImpl();
  }

  /**
   * Build a <code>Configuration</code> for a particular provider
   * implementation. Optionally overrides the provider resolution strategy used
   * to determine the provider.
   * <p/>
   * Used by applications targeting a specific provider programmatically.
   * <p/>
   *
   * <pre>
   * ACMEConfiguration configuration =
   *     Validation.byProvider(ACMEProvider.class)
   *             .providerResolver( new MyResolverStrategy() )
   *             .configure();
   * </pre>
   * , where <code>ACMEConfiguration</code> is the <code>Configuration</code>
   * sub interface uniquely identifying the ACME Bean Validation provider. and
   * <code>ACMEProvider</code> is the <code>ValidationProvider</code>
   * implementation of the ACME provider.
   *
   * @param providerType the <code>ValidationProvider</code> implementation type
   *
   * @return instance building a provider specific <code>Configuration</code>
   *         sub interface implementation.
   */
  public static <T extends Configuration<T>,U extends ValidationProvider<T>>
      ProviderSpecificBootstrap<T> byProvider(Class<U> providerType) {
    return new ProviderSpecificBootstrapImpl<T, U>(providerType);
  }
}
