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

import com.google.gwt.requestfactory.shared.BaseProxy;
import com.google.gwt.requestfactory.shared.Locator;
import com.google.gwt.requestfactory.shared.RequestContext;
import com.google.gwt.requestfactory.shared.ServiceLocator;

import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

import javax.validation.ConstraintViolation;

/**
 * The ServiceLayer mediates all interactions between the
 * {@link SimpleRequestProcessor} and the domain environment. The core service
 * logic can be decorated by extending an {@link ServiceLayerDecorator}.
 * <p>
 * This API is subject to change in future releases.
 *
 * <p><span style='color:red'>RequestFactory has moved to
 * <code>com.google.web.bindery.requestfactory</code>.  This package will be
 * removed in a future version of GWT.</span></p>
 */
@Deprecated
public abstract class ServiceLayer {
  /*
   * NB: This type cannot be directly extended by the user since it has a
   * package-protected constructor. This means that any API-compatibility work
   * that needs to happen can be done in ServiceLayerDecorator in order to keep
   * this interface as clean as possible.
   */

  /**
   * Provides a flag to disable the ServiceLayerCache for debugging purposes.
   */
  private static final boolean ENABLE_CACHE = Boolean.valueOf(System.getProperty(
      "gwt.rf.ServiceLayerCache", "true"));

  /**
   * Create a RequestFactory ServiceLayer that is optionally modified by the
   * given decorators.
   *
   * @param decorators the decorators that will modify the behavior of the core
   *          service layer implementation
   * @return a ServiceLayer instance
   */
  public static ServiceLayer create(ServiceLayerDecorator... decorators) {
    List<ServiceLayerDecorator> list = new ArrayList<ServiceLayerDecorator>();
    // Always hit the cache first
    ServiceLayerDecorator cache =
        ENABLE_CACHE ? new ServiceLayerCache() : new ServiceLayerDecorator();
    list.add(cache);
    // The the user-provided decorators
    if (decorators != null) {
      list.addAll(Arrays.asList(decorators));
    }
    // Support for Locator objects
    list.add(new LocatorServiceLayer());
    // Interact with domain objects
    list.add(new ReflectiveServiceLayer());
    // Locate domain objects
    list.add(new ResolverServiceLayer());

    // Make the last layer point to the cache
    list.get(list.size() - 1).top = cache;

    // Point each entry at the next
    for (int i = list.size() - 2; i >= 0; i--) {
      ServiceLayerDecorator layer = list.get(i);
      layer.next = list.get(i + 1);
      layer.top = cache;
    }

    return cache;
  }

  /**
   * A pointer to the top-most ServiceLayer instance.
   */
  ServiceLayer top;

  /**
   * Not generally-extensible.
   */
  ServiceLayer() {
  }

  /**
   * Create an instance of the requested domain type.
   *
   * @param <T> the requested domain type
   * @param clazz the requested domain type
   * @return an instance of the requested domain type
   */
  public abstract <T> T createDomainObject(Class<T> clazz);

  /**
   * Create an instance of the requested {@link Locator} type.
   *
   * @param <T> the requested Locator type
   * @param clazz the requested Locator type
   * @return an instance of the requested Locator type
   */
  public abstract <T extends Locator<?, ?>> T createLocator(Class<T> clazz);

  /**
   * Create an instance of a service object that can be used as the target for
   * the given method invocation.
   *
   * @param contextMethod a method defined in a RequestContext
   * @param domainMethod the method that the service object must implement
   * @return an instance of the requested service object
   */
  public abstract Object createServiceInstance(Method contextMethod, Method domainMethod);

  /**
   * Returns the ClassLoader that should be used when attempting to access
   * domain classes or resources.
   * <p>
   * The default implementation returns
   * {@code Thread.currentThread().getContextClassLoader()}.
   */
  public abstract ClassLoader getDomainClassLoader();

  /**
   * Determine the method to invoke when retrieving the given property.
   *
   * @param domainType a domain entity type
   * @param property the name of the property to be retrieved
   * @return the Method that should be invoked to retrieve the property or
   *         {@code null} if the method could not be located
   */
  public abstract Method getGetter(Class<?> domainType, String property);

  /**
   * Return the persistent id for a domain object. May return {@code null} to
   * indicate that the domain object has not been persisted. The value returned
   * from this method must be a simple type (e.g. Integer, String) or a domain
   * type for which a mapping to an EntityProxy or Value proxy exists.
   * <p>
   * The values returned from this method may be passed to
   * {@link #loadDomainObject(Class, Object)} in the future.
   *
   * @param domainObject a domain object
   * @return the persistent id of the domain object or {@code null} if the
   *         object is not persistent
   */
  public abstract Object getId(Object domainObject);

  /**
   * Returns the type of object the domain type's {@code findFoo()} or
   * {@link com.google.gwt.requestfactory.shared.Locator#getId(Object)
   * Locator.getId()} expects to receive.
   *
   * @param domainType a domain entity type
   * @return the type of the persistent id value used to represent the domain
   *         type
   */
  public abstract Class<?> getIdType(Class<?> domainType);

  /**
   * Retrieve the named property from the domain object.
   *
   * @param domainObject the domain object being examined
   * @param property the property name
   * @return the value of the property
   */
  public abstract Object getProperty(Object domainObject, String property);

  /**
   * Compute the return type for a method declared in a RequestContext by
   * analyzing the generic method declaration.
   */
  public abstract Type getRequestReturnType(Method contextMethod);

  /**
   * Determine the method to invoke when setting the given property.
   *
   * @param domainType a domain entity type
   * @param property the name of the property to be set
   * @return the Method that should be invoked to set the property or
   *         {@code null} if the method could not be located
   */
  public abstract Method getSetter(Class<?> domainType, String property);

  /**
   * May return {@code null} to indicate that the domain object has not been
   * persisted. The value returned from this method must be a simple type (e.g.
   * Integer, String) or a domain type for which a mapping to an EntityProxy or
   * Value proxy exists.
   *
   * @param domainObject a domain object
   * @return the version of the domain object or {@code null} if the object is
   *         not persistent
   */
  public abstract Object getVersion(Object domainObject);

  /**
   * Invoke a domain service method. The underlying eventually calls
   * {@link Method#invoke(Object, Object...)}.
   *
   * @param domainMethod the method to invoke
   * @param args the arguments to pass to the method
   * @return the value returned from the method invocation
   */
  public abstract Object invoke(Method domainMethod, Object... args);

  /**
   * Returns {@code true} if the given domain object is still live (i.e. not
   * deleted) in the backing store.
   *
   * @param domainObject a domain entity
   * @return {@code true} if {@code domainObject} could be retrieved at a later
   *         point in time
   */
  public abstract boolean isLive(Object domainObject);

  /**
   * Load an object from the backing store. This method may return {@code null}
   * to indicate that the requested object is no longer available.
   *
   * @param <T> the type of object to load
   * @param clazz the type of object to load
   * @param domainId an id previously returned from {@link #getId(Object)}
   * @return the requested object or {@code null} if it is irretrievable
   */
  public abstract <T> T loadDomainObject(Class<T> clazz, Object domainId);

  /**
   * Load multiple objects from the backing store. This method is intended to
   * allow more efficient access to the backing store by providing all objects
   * referenced in an incoming payload.
   * <p>
   * The default implementation of this method will delegate to
   * {@link #loadDomainObject(Class, Object)}.
   *
   * @param classes type type of each object to load
   * @param domainIds the ids previously returned from {@link #getId(Object)}
   * @return the requested objects, elements of which may be {@code null} if the
   *         requested objects were irretrievable
   */
  public abstract List<Object> loadDomainObjects(List<Class<?>> classes, List<Object> domainIds);

  /**
   * Determines if the invocation of a domain method requires a
   * {@link ServiceLocator} as the 0th parameter when passed into
   * {@link #invoke(Method, Object...)}.
   *
   * @param contextMethod a method defined in a RequestContext
   * @param domainMethod a domain method
   * @return {@code true} if a ServiceLocator is required
   */
  public abstract boolean requiresServiceLocator(Method contextMethod, Method domainMethod);

  /**
   * Given a type token previously returned from
   * {@link #resolveTypeToken(Class)}, return the Class literal associated with
   * the token.
   *
   * @param typeToken a string token
   * @return the type represented by the token
   */
  public abstract Class<? extends BaseProxy> resolveClass(String typeToken);

  /**
   * Determine the type used by the client code to represent a given domain
   * type. If multiple proxy types have been mapped to the same domain type, the
   * {@code clientType} parameter is used to ensure assignability.
   *
   * @param domainClass the server-side type to be transported to the client
   * @param clientType the type to which the returned type must be assignable
   * @param required if {@code true} and no mapping is available, throw an
   *          {@link UnexpectedException}, othrewise the method will return
   *          {@code null}
   * @return a class that represents {@code domainClass} on the client which is
   *         assignable to {@code clientType}
   */
  public abstract <T> Class<? extends T> resolveClientType(Class<?> domainClass,
      Class<T> clientType, boolean required);

  /**
   * Determine the domain (server-side) type that the given client type is
   * mapped to.
   *
   * @param clientType a client-side type
   * @return the domain type that {@code clientType} represents
   */
  public abstract Class<?> resolveDomainClass(Class<?> clientType);

  /**
   * Return the domain service method associated with a RequestContext method
   * declaration. The {@code requestContextMethod} will have been previously
   * resolved by {@link #resolveRequestContextMethod(String, String)}.
   *
   * @param requestContextMethod a RequestContext method declaration.
   * @return the domain service method that should be invoked
   */
  public abstract Method resolveDomainMethod(Method requestContextMethod);

  /**
   * Return the type of {@link Locator} that should be used to access the given
   * domain type.
   *
   * @param domainType a domain (server-side) type
   * @return the type of Locator to use, or {@code null} if the type conforms to
   *         the RequestFactory entity protocol
   */
  public abstract Class<? extends Locator<?, ?>> resolveLocator(Class<?> domainType);

  /**
   * Find a RequestContext method declaration by name.
   *
   * @param requestContextClass the fully-qualified binary name of the
   *          RequestContext
   * @param methodName the name of the service method declared within the
   *          RequestContext
   * @return the method declaration, or {@code null} if the method does not
   *         exist
   */
  public abstract Method resolveRequestContextMethod(String requestContextClass, String methodName);

  /**
   * Given a {@link RequestContext} method, find the service class referenced in
   * the {@link Service} or {@link ServiceName} annotation.
   *
   * @param requestContextClass a RequestContext interface
   * @return the type of service to use
   */
  public abstract Class<?> resolveServiceClass(Class<? extends RequestContext> requestContextClass);

  /**
   * Given a RequestContext method declaration, resolve the
   * {@link ServiceLocator} that should be used when invoking the domain method.
   * This method will only be called if {@link #requiresServiceLocator(Method)}
   * returned {@code true} for the associated domain method.
   *
   * @param contextMethod a RequestContext method declaration
   * @param domainMethod the domain method that will be invoked
   * @return the type of ServiceLocator to use
   */
  public abstract Class<? extends ServiceLocator> resolveServiceLocator(Method contextMethod,
      Method domainMethod);

  /**
   * Return a string used to represent the given type in the wire protocol.
   *
   * @param proxyType a client-side EntityProxy or ValueProxy type
   * @return the type token used to represent the proxy type
   */
  public abstract String resolveTypeToken(Class<? extends BaseProxy> proxyType);

  /**
   * Sets a property on a domain object.
   *
   * @param domainObject the domain object to operate on
   * @param property the name of the property to set
   * @param expectedType the type of the property
   * @param value the new value
   */
  public abstract void setProperty(Object domainObject, String property, Class<?> expectedType,
      Object value);

  /**
   * Invoke a JSR 303 validator on the given domain object. If no validator is
   * available, this method is a no-op.
   *
   * @param <T> the type of data being validated
   * @param domainObject the domain objcet to validate
   * @return the violations associated with the domain object
   */
  public abstract <T> Set<ConstraintViolation<T>> validate(T domainObject);
}
