/*
 * 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 com.google.gwt.rpc.server.Pair;

import java.lang.ref.SoftReference;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * A cache for idempotent methods in {@link ServiceLayer}. The caching is
 * separate from {@link ReflectiveServiceLayer} so that the cache can be applied
 * to any decorators injected by the user.
 */
class ServiceLayerCache extends ServiceLayerDecorator {

  /**
   * ConcurrentHashMaps don't allow null keys or values, but sometimes we want
   * to cache a null value.
   */
  private static final Object NULL_MARKER = new Object();

  private static SoftReference<Map<Method, Map<Object, Object>>> methodCache;

  private static final Method createLocator;
  private static final Method createServiceInstance;
  private static final Method getDomainClassLoader;
  private static final Method getGetter;
  private static final Method getIdType;
  private static final Method getRequestReturnType;
  private static final Method getSetter;
  private static final Method requiresServiceLocator;
  private static final Method resolveClass;
  private static final Method resolveClientType;
  private static final Method resolveDomainClass;
  private static final Method resolveDomainMethod;
  private static final Method resolveLocator;
  private static final Method resolveRequestContextMethod;
  private static final Method resolveServiceLocator;
  private static final Method resolveTypeToken;

  static {
    createLocator = getMethod("createLocator", Class.class);
    createServiceInstance = getMethod("createServiceInstance", Method.class, Method.class);
    getDomainClassLoader = getMethod("getDomainClassLoader");
    getGetter = getMethod("getGetter", Class.class, String.class);
    getIdType = getMethod("getIdType", Class.class);
    getRequestReturnType = getMethod("getRequestReturnType", Method.class);
    getSetter = getMethod("getSetter", Class.class, String.class);
    requiresServiceLocator = getMethod("requiresServiceLocator", Method.class, Method.class);
    resolveClass = getMethod("resolveClass", String.class);
    resolveClientType = getMethod("resolveClientType", Class.class, Class.class, boolean.class);
    resolveDomainClass = getMethod("resolveDomainClass", Class.class);
    resolveDomainMethod = getMethod("resolveDomainMethod", Method.class);
    resolveLocator = getMethod("resolveLocator", Class.class);
    resolveRequestContextMethod =
        getMethod("resolveRequestContextMethod", String.class, String.class);
    resolveServiceLocator = getMethod("resolveServiceLocator", Method.class, Method.class);
    resolveTypeToken = getMethod("resolveTypeToken", Class.class);
  }

  private static Map<Method, Map<Object, Object>> getCache() {
    Map<Method, Map<Object, Object>> toReturn = methodCache == null ? null : methodCache.get();
    if (toReturn == null) {
      toReturn = new ConcurrentHashMap<Method, Map<Object, Object>>();
      methodCache = new SoftReference<Map<Method, Map<Object, Object>>>(toReturn);
    }
    return toReturn;
  }

  private static Method getMethod(String name, Class<?>... argTypes) {
    try {
      return ServiceLayer.class.getMethod(name, argTypes);
    } catch (SecurityException e) {
      throw new RuntimeException("Could not set up ServiceLayerCache Methods", e);
    } catch (NoSuchMethodException e) {
      throw new RuntimeException("Could not set up ServiceLayerCache Methods", e);
    }
  }

  private final Map<Method, Map<Object, Object>> methodMap = getCache();

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

  @Override
  public Object createServiceInstance(Method contextMethod, Method domainMethod) {
    return getOrCache(createServiceInstance, new Pair<Method, Method>(contextMethod, domainMethod),
        Object.class, contextMethod, domainMethod);
  }

  @Override
  public ClassLoader getDomainClassLoader() {
    return getOrCache(getDomainClassLoader, NULL_MARKER, ClassLoader.class);
  }

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

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

  @Override
  public Type getRequestReturnType(Method contextMethod) {
    return getOrCache(getRequestReturnType, contextMethod, Type.class, contextMethod);
  }

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

  @Override
  public boolean requiresServiceLocator(Method contextMethod, Method domainMethod) {
    return getOrCache(requiresServiceLocator,
        new Pair<Method, Method>(contextMethod, domainMethod), Boolean.class, contextMethod,
        domainMethod);
  }

  @Override
  public Class<? extends BaseProxy> resolveClass(String typeToken) {
    Class<?> found = getOrCache(resolveClass, typeToken, Class.class, typeToken);
    return found.asSubclass(BaseProxy.class);
  }

  @Override
  public <T> Class<? extends T> resolveClientType(Class<?> domainClass, Class<T> clientType,
      boolean required) {
    Class<?> clazz =
        getOrCache(resolveClientType, new Pair<Class<?>, Class<?>>(domainClass, clientType),
            Class.class, domainClass, clientType, required);
    return clazz == null ? null : clazz.asSubclass(clientType);
  }

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

  @Override
  public Method resolveDomainMethod(Method requestContextMethod) {
    return getOrCache(resolveDomainMethod, requestContextMethod, Method.class, requestContextMethod);
  }

  @Override
  @SuppressWarnings("unchecked")
  public Class<? extends Locator<?, ?>> resolveLocator(Class<?> domainType) {
    return getOrCache(resolveLocator, domainType, Class.class, domainType);
  }

  @Override
  public Method resolveRequestContextMethod(String requestContextClass, String methodName) {
    return getOrCache(resolveRequestContextMethod, new Pair<String, String>(requestContextClass,
        methodName), Method.class, requestContextClass, methodName);
  }

  @Override
  public Class<? extends ServiceLocator> resolveServiceLocator(Method contextMethod,
      Method domainMethod) {
    Class<?> clazz =
        getOrCache(resolveServiceLocator, new Pair<Method, Method>(contextMethod, domainMethod),
            Class.class, contextMethod, domainMethod);
    return clazz == null ? null : clazz.asSubclass(ServiceLocator.class);
  }

  @Override
  public String resolveTypeToken(Class<? extends BaseProxy> domainClass) {
    return getOrCache(resolveTypeToken, domainClass, String.class, domainClass);
  }

  private <K, T> T getOrCache(Method method, K key, Class<T> valueType, Object... args) {
    Map<Object, Object> map = methodMap.get(method);
    if (map == null) {
      map = new ConcurrentHashMap<Object, Object>();
      methodMap.put(method, map);
    }
    Object raw = map.get(key);
    if (raw == NULL_MARKER) {
      return null;
    }
    T toReturn = valueType.cast(raw);
    if (toReturn == null) {
      Throwable ex = null;
      try {
        toReturn = valueType.cast(method.invoke(getNext(), args));
        map.put(key, toReturn == null ? NULL_MARKER : toReturn);
      } catch (InvocationTargetException e) {
        // The next layer threw an exception
        Throwable cause = e.getCause();
        if (cause instanceof RuntimeException) {
          // Re-throw RuntimeExceptions, which likely originate from die()
          throw ((RuntimeException) cause);
        }
        die(cause, "Unexpected checked exception");
      } catch (IllegalArgumentException e) {
        ex = e;
      } catch (IllegalAccessException e) {
        ex = e;
      }
      if (ex != null) {
        die(ex, "Bad method invocation");
      }
    }
    return toReturn;
  }
}
