/*
 * Copyright (C) 2016 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.googlecode.android_scripting.rpc;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcelable;

import com.googlecode.android_scripting.facade.AndroidFacade;
import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
import com.googlecode.android_scripting.jsonrpc.RpcReceiverManager;
import com.googlecode.android_scripting.util.VisibleForTesting;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

/**
 * An adapter that wraps {@code Method}.
 *
 * @author igor.v.karp@gmail.com (Igor Karp)
 */
public final class MethodDescriptor {
  private static final Map<Class<?>, Converter<?>> sConverters = populateConverters();

  private final Method mMethod;
  private final Class<? extends RpcReceiver> mClass;

  public MethodDescriptor(Class<? extends RpcReceiver> clazz, Method method) {
    mClass = clazz;
    mMethod = method;
  }

  @Override
  public String toString() {
    return mMethod.getDeclaringClass().getCanonicalName() + "." + mMethod.getName();
  }

  /** Collects all methods with {@code RPC} annotation from given class. */
  public static Collection<MethodDescriptor> collectFrom(Class<? extends RpcReceiver> clazz) {
    List<MethodDescriptor> descriptors = new ArrayList<MethodDescriptor>();
    for (Method method : clazz.getMethods()) {
      if (method.isAnnotationPresent(Rpc.class)) {
        descriptors.add(new MethodDescriptor(clazz, method));
      }
    }
    return descriptors;
  }

  /**
   * Invokes the call that belongs to this object with the given parameters. Wraps the response
   * (possibly an exception) in a JSONObject.
   *
   * @param parameters
   *          {@code JSONArray} containing the parameters
   * @return result
   * @throws Throwable
   */
  public Object invoke(RpcReceiverManager manager, final JSONArray parameters) throws Throwable {

    final Type[] parameterTypes = getGenericParameterTypes();
    final Object[] args = new Object[parameterTypes.length];
    final Annotation annotations[][] = getParameterAnnotations();

    if (parameters.length() > args.length) {
      throw new RpcError("Too many parameters specified.");
    }

    for (int i = 0; i < args.length; i++) {
      final Type parameterType = parameterTypes[i];
      if (i < parameters.length()) {
        args[i] = convertParameter(parameters, i, parameterType);
      } else if (MethodDescriptor.hasDefaultValue(annotations[i])) {
        args[i] = MethodDescriptor.getDefaultValue(parameterType, annotations[i]);
      } else {
        throw new RpcError("Argument " + (i + 1) + " is not present");
      }
    }

    return invoke(manager, args);
  }

  /**
   * Invokes the call that belongs to this object with the given parameters. Wraps the response
   * (possibly an exception) in a JSONObject.
   *
   * @param parameters {@code Bundle} containing the parameters
   * @return result
   * @throws Throwable
   */
  public Object invoke(RpcReceiverManager manager, final Bundle parameters) throws Throwable {
    final Annotation annotations[][] = getParameterAnnotations();
    final Class<?>[] parameterTypes = getMethod().getParameterTypes();
    final Object[] args = new Object[parameterTypes.length];

    for (int i = 0; i < parameterTypes.length; i++) {
      Class<?> parameterType = parameterTypes[i];
      String parameterName = getName(annotations[i]);
      if (i < parameterTypes.length) {
        args[i] = convertParameter(parameters, parameterType, parameterName);
      } else if (MethodDescriptor.hasDefaultValue(annotations[i])) {
        args[i] = MethodDescriptor.getDefaultValue(parameterType, annotations[i]);
      } else {
        throw new RpcError("Argument " + (i + 1) + " is not present");
      }
    }
    return invoke(manager, args);
  }

  private Object invoke(RpcReceiverManager manager, Object[] args) throws Throwable{
    Object result = null;
    try {
      result = manager.invoke(mClass, mMethod, args);
    } catch (Throwable t) {
      throw t.getCause();
    }
    return result;
  }

  /**
   * Converts a parameter from JSON into a Java Object.
   *
   * @return TODO
   */
  // TODO(damonkohler): This signature is a bit weird (auto-refactored). The obvious alternative
  // would be to work on one supplied parameter and return the converted parameter. However, that's
  // problematic because you lose the ability to call the getXXX methods on the JSON array.
  @VisibleForTesting
  static Object convertParameter(final JSONArray parameters, int index, Type type)
      throws JSONException, RpcError {
    try {
      // Log.d("sl4a", parameters.toString());
      // Log.d("sl4a", type.toString());
      // We must handle null and numbers explicitly because we cannot magically cast them. We
      // also need to convert implicitly from numbers to bools.
      if (parameters.isNull(index)) {
        return null;
      } else if (type == Boolean.class) {
        try {
          return parameters.getBoolean(index);
        } catch (JSONException e) {
          return new Boolean(parameters.getInt(index) != 0);
        }
      } else if (type == Long.class) {
        return parameters.getLong(index);
      } else if (type == Double.class) {
        return parameters.getDouble(index);
      } else if (type == Integer.class) {
        return parameters.getInt(index);
      } else if (type == Intent.class) {
        return buildIntent(parameters.getJSONObject(index));
      } else if (type == Integer[].class) {
        JSONArray list = parameters.getJSONArray(index);
        Integer[] result = new Integer[list.length()];
        for (int i = 0; i < list.length(); i++) {
          result[i] = list.getInt(i);
        }
        return result;
      } else if (type == String[].class) {
        JSONArray list = parameters.getJSONArray(index);
        String[] result = new String[list.length()];
        for (int i = 0; i < list.length(); i++) {
          result[i] = list.getString(i);
        }
        return result;
      } else if (type == JSONObject.class) {
          return parameters.getJSONObject(index);
      } else {
        // Magically cast the parameter to the right Java type.
        return ((Class<?>) type).cast(parameters.get(index));
      }
    } catch (ClassCastException e) {
      throw new RpcError("Argument " + (index + 1) + " should be of type "
          + ((Class<?>) type).getSimpleName() + ".");
    }
  }

  private Object convertParameter(Bundle bundle, Class<?> type, String name) {
    Object param = null;
    if (type.isAssignableFrom(Boolean.class)) {
      param = bundle.getBoolean(name, false);
    }
    if (type.isAssignableFrom(Boolean[].class)) {
      param = bundle.getBooleanArray(name);
    }
    if (type.isAssignableFrom(String.class)) {
      param = bundle.getString(name);
    }
    if (type.isAssignableFrom(String[].class)) {
      param = bundle.getStringArray(name);
    }
    if (type.isAssignableFrom(Integer.class)) {
      param = bundle.getInt(name, 0);
    }
    if (type.isAssignableFrom(Integer[].class)) {
      param = bundle.getIntArray(name);
    }
    if (type.isAssignableFrom(Bundle.class)) {
      param = bundle.getBundle(name);
    }
    if (type.isAssignableFrom(Parcelable.class)) {
      param = bundle.getParcelable(name);
    }
    if (type.isAssignableFrom(Parcelable[].class)) {
      param = bundle.getParcelableArray(name);
    }
    if (type.isAssignableFrom(Intent.class)) {
      param = bundle.getParcelable(name);
    }
    return param;
  }

  public static Object buildIntent(JSONObject jsonObject) throws JSONException {
    Intent intent = new Intent();
    if (jsonObject.has("action")) {
      intent.setAction(jsonObject.getString("action"));
    }
    if (jsonObject.has("data") && jsonObject.has("type")) {
      intent.setDataAndType(Uri.parse(jsonObject.optString("data", null)),
          jsonObject.optString("type", null));
    } else if (jsonObject.has("data")) {
      intent.setData(Uri.parse(jsonObject.optString("data", null)));
    } else if (jsonObject.has("type")) {
      intent.setType(jsonObject.optString("type", null));
    }
    if (jsonObject.has("packagename") && jsonObject.has("classname")) {
      intent.setClassName(jsonObject.getString("packagename"), jsonObject.getString("classname"));
    }
    if (jsonObject.has("flags")) {
      intent.setFlags(jsonObject.getInt("flags"));
    }
    if (!jsonObject.isNull("extras")) {
      AndroidFacade.putExtrasFromJsonObject(jsonObject.getJSONObject("extras"), intent);
    }
    if (!jsonObject.isNull("categories")) {
      JSONArray categories = jsonObject.getJSONArray("categories");
      for (int i = 0; i < categories.length(); i++) {
        intent.addCategory(categories.getString(i));
      }
    }
    return intent;
  }

  public Method getMethod() {
    return mMethod;
  }

  public Class<? extends RpcReceiver> getDeclaringClass() {
    return mClass;
  }

  public String getName() {
    if (mMethod.isAnnotationPresent(RpcName.class)) {
      return mMethod.getAnnotation(RpcName.class).name();
    }
    return mMethod.getName();
  }

  public Type[] getGenericParameterTypes() {
    return mMethod.getGenericParameterTypes();
  }

  public Annotation[][] getParameterAnnotations() {
    return mMethod.getParameterAnnotations();
  }

  /**
   * Returns a human-readable help text for this RPC, based on annotations in the source code.
   *
   * @return derived help string
   */
  public String getHelp() {
    StringBuilder helpBuilder = new StringBuilder();
    Rpc rpcAnnotation = mMethod.getAnnotation(Rpc.class);

    helpBuilder.append(mMethod.getName());
    helpBuilder.append("(");
    final Class<?>[] parameterTypes = mMethod.getParameterTypes();
    final Type[] genericParameterTypes = mMethod.getGenericParameterTypes();
    final Annotation[][] annotations = mMethod.getParameterAnnotations();
    for (int i = 0; i < parameterTypes.length; i++) {
      if (i == 0) {
        helpBuilder.append("\n  ");
      } else {
        helpBuilder.append(",\n  ");
      }

      helpBuilder.append(getHelpForParameter(genericParameterTypes[i], annotations[i]));
    }
    helpBuilder.append(")\n\n");
    helpBuilder.append(rpcAnnotation.description());
    if (!rpcAnnotation.returns().equals("")) {
      helpBuilder.append("\n");
      helpBuilder.append("\nReturns:\n  ");
      helpBuilder.append(rpcAnnotation.returns());
    }

    if (mMethod.isAnnotationPresent(RpcStartEvent.class)) {
      String eventName = mMethod.getAnnotation(RpcStartEvent.class).value();
      helpBuilder.append(String.format("\n\nGenerates \"%s\" events.", eventName));
    }

    if (mMethod.isAnnotationPresent(RpcDeprecated.class)) {
      String replacedBy = mMethod.getAnnotation(RpcDeprecated.class).value();
      String release = mMethod.getAnnotation(RpcDeprecated.class).release();
      helpBuilder.append(String.format("\n\nDeprecated in %s! Please use %s instead.", release,
          replacedBy));
    }

    return helpBuilder.toString();
  }

  /**
   * Returns the help string for one particular parameter. This respects optional parameters.
   *
   * @param parameterType
   *          (generic) type of the parameter
   * @param annotations
   *          annotations of the parameter, may be null
   * @return string describing the parameter based on source code annotations
   */
  private static String getHelpForParameter(Type parameterType, Annotation[] annotations) {
    StringBuilder result = new StringBuilder();

    appendTypeName(result, parameterType);
    result.append(" ");
    result.append(getName(annotations));
    if (hasDefaultValue(annotations)) {
      result.append("[optional");
      if (hasExplicitDefaultValue(annotations)) {
        result.append(", default " + getDefaultValue(parameterType, annotations));
      }
      result.append("]");
    }

    String description = getDescription(annotations);
    if (description.length() > 0) {
      result.append(": ");
      result.append(description);
    }

    return result.toString();
  }

  /**
   * Appends the name of the given type to the {@link StringBuilder}.
   *
   * @param builder
   *          string builder to append to
   * @param type
   *          type whose name to append
   */
  private static void appendTypeName(final StringBuilder builder, final Type type) {
    if (type instanceof Class<?>) {
      builder.append(((Class<?>) type).getSimpleName());
    } else {
      ParameterizedType parametrizedType = (ParameterizedType) type;
      builder.append(((Class<?>) parametrizedType.getRawType()).getSimpleName());
      builder.append("<");

      Type[] arguments = parametrizedType.getActualTypeArguments();
      for (int i = 0; i < arguments.length; i++) {
        if (i > 0) {
          builder.append(", ");
        }
        appendTypeName(builder, arguments[i]);
      }
      builder.append(">");
    }
  }

  /**
   * Returns parameter descriptors suitable for the RPC call text representation.
   *
   * <p>
   * Uses parameter value, default value or name, whatever is available first.
   *
   * @return an array of parameter descriptors
   */
  public ParameterDescriptor[] getParameterValues(String[] values) {
    Type[] parameterTypes = mMethod.getGenericParameterTypes();
    Annotation[][] parametersAnnotations = mMethod.getParameterAnnotations();
    ParameterDescriptor[] parameters = new ParameterDescriptor[parametersAnnotations.length];
    for (int index = 0; index < parameters.length; index++) {
      String value;
      if (index < values.length) {
        value = values[index];
      } else if (hasDefaultValue(parametersAnnotations[index])) {
        Object defaultValue = getDefaultValue(parameterTypes[index], parametersAnnotations[index]);
        if (defaultValue == null) {
          value = null;
        } else {
          value = String.valueOf(defaultValue);
        }
      } else {
        value = getName(parametersAnnotations[index]);
      }
      parameters[index] = new ParameterDescriptor(value, parameterTypes[index]);
    }
    return parameters;
  }

  /**
   * Returns parameter hints.
   *
   * @return an array of parameter hints
   */
  public String[] getParameterHints() {
    Annotation[][] parametersAnnotations = mMethod.getParameterAnnotations();
    String[] hints = new String[parametersAnnotations.length];
    for (int index = 0; index < hints.length; index++) {
      String name = getName(parametersAnnotations[index]);
      String description = getDescription(parametersAnnotations[index]);
      String hint = "No paramenter description.";
      if (!name.equals("") && !description.equals("")) {
        hint = name + ": " + description;
      } else if (!name.equals("")) {
        hint = name;
      } else if (!description.equals("")) {
        hint = description;
      }
      hints[index] = hint;
    }
    return hints;
  }

  /**
   * Extracts the formal parameter name from an annotation.
   *
   * @param annotations
   *          the annotations of the parameter
   * @return the formal name of the parameter
   */
  private static String getName(Annotation[] annotations) {
    for (Annotation a : annotations) {
      if (a instanceof RpcParameter) {
        return ((RpcParameter) a).name();
      }
    }
    throw new IllegalStateException("No parameter name");
  }

  /**
   * Extracts the parameter description from its annotations.
   *
   * @param annotations
   *          the annotations of the parameter
   * @return the description of the parameter
   */
  private static String getDescription(Annotation[] annotations) {
    for (Annotation a : annotations) {
      if (a instanceof RpcParameter) {
        return ((RpcParameter) a).description();
      }
    }
    throw new IllegalStateException("No parameter description");
  }

  /**
   * Returns the default value for a specific parameter.
   *
   * @param parameterType
   *          parameterType
   * @param annotations
   *          annotations of the parameter
   */
  public static Object getDefaultValue(Type parameterType, Annotation[] annotations) {
    for (Annotation a : annotations) {
      if (a instanceof RpcDefault) {
        RpcDefault defaultAnnotation = (RpcDefault) a;
        Converter<?> converter = converterFor(parameterType, defaultAnnotation.converter());
        return converter.convert(defaultAnnotation.value());
      } else if (a instanceof RpcOptional) {
        return null;
      }
    }
    throw new IllegalStateException("No default value for " + parameterType);
  }

  @SuppressWarnings("rawtypes")
  private static Converter<?> converterFor(Type parameterType,
      Class<? extends Converter> converterClass) {
    if (converterClass == Converter.class) {
      Converter<?> converter = sConverters.get(parameterType);
      if (converter == null) {
        throw new IllegalArgumentException("No predefined converter found for " + parameterType);
      }
      return converter;
    }
    try {
      Constructor<?> constructor = converterClass.getConstructor(new Class<?>[0]);
      return (Converter<?>) constructor.newInstance(new Object[0]);
    } catch (Exception e) {
      throw new IllegalArgumentException("Cannot create converter from "
          + converterClass.getCanonicalName());
    }
  }

  /**
   * Determines whether or not this parameter has default value.
   *
   * @param annotations
   *          annotations of the parameter
   */
  public static boolean hasDefaultValue(Annotation[] annotations) {
    for (Annotation a : annotations) {
      if (a instanceof RpcDefault || a instanceof RpcOptional) {
        return true;
      }
    }
    return false;
  }

  /**
   * Returns whether the default value is specified for a specific parameter.
   *
   * @param annotations
   *          annotations of the parameter
   */
  @VisibleForTesting
  static boolean hasExplicitDefaultValue(Annotation[] annotations) {
    for (Annotation a : annotations) {
      if (a instanceof RpcDefault) {
        return true;
      }
    }
    return false;
  }

  /** Returns the converters for {@code String}, {@code Integer} and {@code Boolean}. */
  private static Map<Class<?>, Converter<?>> populateConverters() {
    Map<Class<?>, Converter<?>> converters = new HashMap<Class<?>, Converter<?>>();
    converters.put(String.class, new Converter<String>() {
      @Override
      public String convert(String value) {
        return value;
      }
    });
    converters.put(Integer.class, new Converter<Integer>() {
      @Override
      public Integer convert(String input) {
        try {
          return Integer.decode(input);
        } catch (NumberFormatException e) {
          throw new IllegalArgumentException("'" + input + "' is not an integer");
        }
      }
    });
    converters.put(Boolean.class, new Converter<Boolean>() {
      @Override
      public Boolean convert(String input) {
        if (input == null) {
          return null;
        }
        input = input.toLowerCase();
        if (input.equals("true")) {
          return Boolean.TRUE;
        }
        if (input.equals("false")) {
          return Boolean.FALSE;
        }
        throw new IllegalArgumentException("'" + input + "' is not a boolean");
      }
    });
    return converters;
  }
}
