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

import com.google.web.bindery.requestfactory.shared.BaseProxy;
import com.google.web.bindery.requestfactory.shared.Locator;
import com.google.web.bindery.requestfactory.shared.RequestContext;
import com.google.web.bindery.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.
 */
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);

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

  /**
   * 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.web.bindery.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
   *          exception, otherwise 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, 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);
}
