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

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.validation.ConstraintViolation;

/**
 * Users that intend to alter how RequestFactory interacts with the domain
 * environment can extend this type and provide it to
 * {@link ServiceLayer#create(ServiceLayerDecorator...)}. The methods defined in
 * this type will automatically delegate to the next decorator or the root
 * service object after being processed by{@code create()}.
 */
public class ServiceLayerDecorator extends ServiceLayer {
  private static final Logger log = Logger.getLogger(ServiceLayer.class.getName());

  /**
   * A pointer to the next deepest layer.
   */
  ServiceLayer next;

  @Override
  public <T> T createDomainObject(Class<T> clazz) {
    return getNext().createDomainObject(clazz);
  }

  @Override
  public <T extends Locator<?, ?>> T createLocator(Class<T> clazz) {
    return getNext().createLocator(clazz);
  }

  @Override
  public Object createServiceInstance(Method contextMethod, Method domainMethod) {
    return getNext().createServiceInstance(contextMethod, domainMethod);
  }

  @Override
  public ClassLoader getDomainClassLoader() {
    return getNext().getDomainClassLoader();
  }

  @Override
  public Method getGetter(Class<?> domainType, String property) {
    return getNext().getGetter(domainType, property);
  }

  @Override
  public Object getId(Object domainObject) {
    return getNext().getId(domainObject);
  }

  @Override
  public Class<?> getIdType(Class<?> domainType) {
    return getNext().getIdType(domainType);
  }

  @Override
  public Object getProperty(Object domainObject, String property) {
    return getNext().getProperty(domainObject, property);
  }

  @Override
  public Type getRequestReturnType(Method contextMethod) {
    return getNext().getRequestReturnType(contextMethod);
  }

  @Override
  public Method getSetter(Class<?> domainType, String property) {
    return getNext().getSetter(domainType, property);
  }

  @Override
  public Object getVersion(Object domainObject) {
    return getNext().getVersion(domainObject);
  }

  @Override
  public Object invoke(Method domainMethod, Object... args) {
    return getNext().invoke(domainMethod, args);
  }

  @Override
  public boolean isLive(Object domainObject) {
    return getNext().isLive(domainObject);
  }

  @Override
  public <T> T loadDomainObject(Class<T> clazz, Object domainId) {
    return getNext().loadDomainObject(clazz, domainId);
  }

  @Override
  public List<Object> loadDomainObjects(List<Class<?>> classes, List<Object> domainIds) {
    return getNext().loadDomainObjects(classes, domainIds);
  }

  @Override
  public boolean requiresServiceLocator(Method contextMethod, Method domainMethod) {
    return getNext().requiresServiceLocator(contextMethod, domainMethod);
  }

  @Override
  public Class<? extends BaseProxy> resolveClass(String typeToken) {
    return getNext().resolveClass(typeToken);
  }

  @Override
  public <T> Class<? extends T> resolveClientType(Class<?> domainClass, Class<T> clientType,
      boolean required) {
    return getNext().resolveClientType(domainClass, clientType, required);
  }

  @Override
  public Class<?> resolveDomainClass(Class<?> clazz) {
    return getNext().resolveDomainClass(clazz);
  }

  @Override
  public Method resolveDomainMethod(Method requestContextMethod) {
    return getNext().resolveDomainMethod(requestContextMethod);
  }

  @Override
  public Class<? extends Locator<?, ?>> resolveLocator(Class<?> domainType) {
    return getNext().resolveLocator(domainType);
  }

  @Override
  public Method resolveRequestContextMethod(String requestContextClass, String methodName) {
    return getNext().resolveRequestContextMethod(requestContextClass, methodName);
  }

  @Override
  public Class<? extends ServiceLocator> resolveServiceLocator(Method contextMethod,
      Method domainMethod) {
    return getNext().resolveServiceLocator(contextMethod, domainMethod);
  }

  @Override
  public String resolveTypeToken(Class<? extends BaseProxy> proxyType) {
    return getNext().resolveTypeToken(proxyType);
  }

  @Override
  public void setProperty(Object domainObject, String property, Class<?> expectedType, Object value) {
    getNext().setProperty(domainObject, property, expectedType, value);
  }

  @Override
  public <T> Set<ConstraintViolation<T>> validate(T domainObject) {
    return getNext().validate(domainObject);
  }

  /**
   * Throw a fatal error up into the top-level processing code. This method
   * should be used to provide diagnostic information that will help the
   * end-developer track down problems when that data would expose
   * implementation details of the server to the client.
   * 
   * @param e a throwable with more data, may be {@code null}
   * @param message a printf-style format string
   * @param args arguments for the message
   * @throws UnexpectedException this method never returns normally
   * @see #report(String, Object...)
   */
  protected final <T> T die(Throwable e, String message, Object... args) throws UnexpectedException {
    String msg = String.format(message, args);
    log.log(Level.SEVERE, msg, e);
    throw new UnexpectedException(msg, e);
  }

  /**
   * Returns the top-most service layer. General-purpose ServiceLayer decorators
   * should use the instance provided by {@code getTop()} when calling public
   * methods on the ServiceLayer API to allow higher-level decorators to
   * override behaviors built into lower-level decorators.
   * 
   * @return the ServiceLayer returned by
   *         {@link #create(ServiceLayerDecorator...)}
   */
  protected final ServiceLayer getTop() {
    return top;
  }

  /**
   * Report an exception thrown by code that is under the control of the
   * end-developer.
   * 
   * @param an {@link InvocationTargetException} thrown by an invocation of
   *          user-provided code
   * @throws ReportableException this method never returns normally
   */
  protected final <T> T report(InvocationTargetException userGeneratedException)
      throws ReportableException {
    throw new ReportableException(userGeneratedException.getCause());
  }

  /**
   * Return a message to the client. This method should not include any data
   * that was not sent to the server by the client to avoid leaking data.
   * 
   * @param msg a printf-style format string
   * @param args arguments for the message
   * @throws ReportableException this method never returns normally
   * @see #die(Throwable, String, Object...)
   */
  protected final <T> T report(String msg, Object... args) throws ReportableException {
    throw new ReportableException(String.format(msg, args));
  }

  /**
   * Retrieves the next service layer. Used only by the server-package code and
   * accessed by used code via {@code super.doSomething()}.
   */
  final ServiceLayer getNext() {
    if (next == null) {
      // Unexpected, all methods should be implemented by some layer
      throw new UnsupportedOperationException();
    }
    return next;
  }
}
