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

import com.google.gwt.autobean.shared.AutoBean;

import java.beans.Introspector;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * Breakout of method types that an AutoBean shim interface can implement. The
 * order of the values of the enum is important.
 *
 * <p><span style='color:red'>AutoBeans has moved to
 * <code>com.google.web.bindery.autobeans</code>.  This package will be
 * removed in a future version of GWT.</span></p>
 *
 * @see com.google.gwt.autobean.rebind.model.JBeanMethod
 */
@Deprecated
public enum BeanMethod {
  /**
   * Methods defined in Object.
   */
  OBJECT {

    @Override
    public String inferName(Method method) {
      throw new UnsupportedOperationException();
    }

    @Override
    Object invoke(SimpleBeanHandler<?> handler, Method method, Object[] args)
        throws Throwable {
      if (CALL.matches(handler, method)) {
        return CALL.invoke(handler, method, args);
      }
      return method.invoke(handler, args);
    }

    @Override
    boolean matches(SimpleBeanHandler<?> handler, Method method) {
      return method.getDeclaringClass().equals(Object.class);
    }
  },
  /**
   * Getters.
   */
  GET {
    @Override
    public String inferName(Method method) {
      String name = method.getName();
      if (name.startsWith(IS_PREFIX)) {
        Class<?> returnType = method.getReturnType();
        if (Boolean.TYPE.equals(returnType) || Boolean.class.equals(returnType)) {
          return Introspector.decapitalize(name.substring(2));
        }
      }
      return super.inferName(method);
    }

    @Override
    Object invoke(SimpleBeanHandler<?> handler, Method method, Object[] args) {
      String propertyName = inferName(method);
      Object toReturn = handler.getBean().getValues().get(propertyName);
      if (toReturn == null && method.getReturnType().isPrimitive()) {
        toReturn = TypeUtils.getDefaultPrimitiveValue(method.getReturnType());
      }
      return toReturn;
    }

    @Override
    boolean matches(SimpleBeanHandler<?> handler, Method method) {
      Class<?> returnType = method.getReturnType();
      if (method.getParameterTypes().length != 0
          || Void.TYPE.equals(returnType)) {
        return false;
      }

      String name = method.getName();
      if (Boolean.TYPE.equals(returnType) || Boolean.class.equals(returnType)) {
        if (name.startsWith(IS_PREFIX) && name.length() > 2
            || name.startsWith(HAS_PREFIX) && name.length() > 3) {
          return true;
        }
      }
      return name.startsWith(GET_PREFIX) && name.length() > 3;
    }
  },
  /**
   * Setters.
   */
  SET {
    @Override
    Object invoke(SimpleBeanHandler<?> handler, Method method, Object[] args) {
      handler.getBean().getValues().put(inferName(method), args[0]);
      return null;
    }

    @Override
    boolean matches(SimpleBeanHandler<?> handler, Method method) {
      String name = method.getName();
      return name.startsWith(SET_PREFIX) && name.length() > 3
          && method.getParameterTypes().length == 1
          && method.getReturnType().equals(Void.TYPE);
    }
  },
  /**
   * A setter that returns a type assignable from the interface in which the
   * method is declared to support chained, builder-pattern setters. For
   * example, {@code foo.setBar(1).setBaz(42)}.
   */
  SET_BUILDER {
    @Override
    Object invoke(SimpleBeanHandler<?> handler, Method method, Object[] args) {
      handler.getBean().getValues().put(inferName(method), args[0]);
      return handler.getBean().as();
    }

    @Override
    boolean matches(SimpleBeanHandler<?> handler, Method method) {
      String name = method.getName();
      return name.startsWith(SET_PREFIX)
          && name.length() > 3
          && method.getParameterTypes().length == 1
          && method.getReturnType().isAssignableFrom(method.getDeclaringClass());
    }
  },
  /**
   * Domain methods.
   */
  CALL {
    @Override
    public String inferName(Method method) {
      throw new UnsupportedOperationException();
    }

    @Override
    Object invoke(SimpleBeanHandler<?> handler, Method method, Object[] args)
        throws Throwable {
      if (args == null) {
        args = EMPTY_OBJECT;
      }

      Method found = findMethod(handler, method);
      if (found != null) {
        Object[] realArgs = new Object[args.length + 1];
        realArgs[0] = handler.getBean();
        System.arraycopy(args, 0, realArgs, 1, args.length);
        return found.invoke(null, realArgs);
      }
      throw new RuntimeException("Could not find category implementation of "
          + method.toGenericString());
    }

    @Override
    boolean matches(SimpleBeanHandler<?> handler, Method method) {
      return handler.getBean().isWrapper()
          || !handler.getBean().getConfiguration().getCategories().isEmpty()
          && findMethod(handler, method) != null;
    }
  };

  public static final String GET_PREFIX = "get";
  public static final String HAS_PREFIX = "has";
  public static final String IS_PREFIX = "is";
  public static final String SET_PREFIX = "set";

  private static final Object[] EMPTY_OBJECT = new Object[0];

  static Method findMethod(SimpleBeanHandler<?> handler, Method method) {
    Class<?>[] declaredParams = method.getParameterTypes();
    Class<?>[] searchParams = new Class<?>[declaredParams.length + 1];
    searchParams[0] = AutoBean.class;
    System.arraycopy(declaredParams, 0, searchParams, 1, declaredParams.length);
    Class<?> autoBeanType = handler.getBean().getType();

    for (Class<?> clazz : handler.getBean().getConfiguration().getCategories()) {
      try {
        Method found = clazz.getMethod(method.getName(), searchParams);
        if (!Modifier.isStatic(found.getModifiers())) {
          continue;
        }
        // Check the AutoBean parameterization of the 0th argument
        Class<?> foundAutoBean = TypeUtils.ensureBaseType(TypeUtils.getSingleParameterization(
            AutoBean.class, found.getGenericParameterTypes()[0]));
        if (!foundAutoBean.isAssignableFrom(autoBeanType)) {
          continue;
        }
        return found;
      } catch (NoSuchMethodException expected) {
      } catch (IllegalArgumentException e) {
        throw new RuntimeException(e);
      }
    }
    return null;
  }

  public String inferName(Method method) {
    return Introspector.decapitalize(method.getName().substring(3));
  }

  /**
   * Convenience method, not valid for {@link BeanMethod#CALL}.
   */
  public boolean matches(Method method) {
    return matches(null, method);
  }

  /**
   * Invoke the method.
   */
  abstract Object invoke(SimpleBeanHandler<?> handler, Method method,
      Object[] args) throws Throwable;

  /**
   * Determine if the method maches the given type.
   */
  abstract boolean matches(SimpleBeanHandler<?> handler, Method method);
}
