content: /*
   * Created by LuaView.
   * Copyright (c) 2017, Alibaba Group. All rights reserved.
   *
   * This source code is licensed under the MIT.
   * For the full copyright and license information,please view the LICENSE file in the root directory of this source tree.
   */
  
  package com.taobao.luaview.fun.base;
  
  import com.taobao.luaview.cache.AppCache;
  import com.taobao.luaview.global.LuaViewConfig;
  import com.taobao.luaview.userdata.base.BaseUserdata;
  import com.taobao.luaview.util.LogUtil;
  
  import org.luaj.vm2.LuaValue;
  import org.luaj.vm2.Varargs;
  import org.luaj.vm2.lib.VarArgFunction;
  
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.List;
  
  /**
   * 基础多参数函数
   *
   * @author song
   * @date 15/8/14
   */
  public abstract class BaseMethodMapper<U extends LuaValue> extends VarArgFunction {
      private static final String CACHE_METHODS = AppCache.CACHE_METHODS;
  
      /**
       * 该函数使用反射，调用方法，并且被调用方法签名必须为：fun(UIView, Varargs)格式，否则不被支持
       * 所有的method都是被注册的public方法，使用class.getMethods返回
       * TODO 如果这里性能受限的话，考虑使用其他方式实现(反射性能大概低了20倍)，但是只会在创建的时候消耗，其他情况下不消耗性能
       *
       * @param args the arguments to the function call.
       * @return
       */
      public Varargs invoke(Varargs args) {
          try {
              if (opcode != -1) {
                  return invoke(opcode, getUD(args), args);
              } else {
                  return (Varargs) method.invoke(this, getUD(args), args);
              }
          } catch (Exception e) {
              if (LuaViewConfig.isDebug()) {
                  LogUtil.e("[----Method Invoke Error Start----]");
                  LogUtil.e("[Class]", getClass());
                  LogUtil.e("[Opcode]", opcode);
                  LogUtil.e("[Method]", method != null ? method : getMethodByOpcode(opcode));
                  LogUtil.e("[Arguments]", args);
                  LogUtil.e("[Target]", getTarget(args));
                  LogUtil.e("[Error]", e);
                  LogUtil.e("[----Method Invoke Error End----]");
              }
              e.printStackTrace();
              return NONE;
          }
      }
  
      /**
       * 获取userdata
       *
       * @param varargs
       * @return
       */
      public U getUD(Varargs varargs) {
          return (U) varargs.arg1();
      }
  
      public Object getTarget(Varargs varargs) {
          U target = getUD(varargs);
          if (target instanceof BaseUserdata) {
              return ((BaseUserdata) target).userdata();
          }
          return target;
      }
  
      //----------------------------------------------------------------------------------------------
  
      /**
       * merge function names with cache tag
       *
       * @param tag
       * @param supernames
       * @param names
       * @return
       */
      public List<String> mergeFunctionNames(final String tag, final List<String> supernames, final String[] names) {
          List<String> result = AppCache.getCache(CACHE_METHODS).get(tag);
          if (result == null) {
              result = mergeFunctionNames(supernames, names);
              AppCache.getCache(CACHE_METHODS).put(tag, result);
          }
          return result;
      }
  
      public List<String> mergeFunctionNames(final String tag, final List<String> supernames, final List<String> names) {
          List<String> result = AppCache.getCache(CACHE_METHODS).get(tag);
          if (result == null) {
              result = mergeFunctionNames(supernames, names);
              AppCache.getCache(CACHE_METHODS).put(tag, result);
          }
          return result;
      }
  
      /**
       * merge function names
       * 将names拼接在supernames之后
       *
       * @param supernames
       * @param names
       * @return
       */
      private List<String> mergeFunctionNames(final List<String> supernames, final String[] names) {
          return mergeFunctionNames(supernames, Arrays.asList(names));
      }
  
      /**
       * merge FunctionNames
       * 将自己的names拼接在supernames之后
       */
      private List<String> mergeFunctionNames(final List<String> supernames, final List<String> names) {
          final List<String> result = new ArrayList<String>();
          if (supernames != null && supernames.size() > 0) {
              result.addAll(supernames);
          }
          if (supernames != null && names != null) {
              result.addAll(supernames.size(), names);
          }
          return result;
      }
  
      /**
       * 获取所有函数名称，供子类调用
       *
       * @return
       */
      public List<String> getAllFunctionNames() {
          return new ArrayList<String>();
      }
  
      /**
       * 根据code获取函数名称
       *
       * @param optcode
       * @return
       */
      public String getMethodByOpcode(int optcode) {
          List<String> allMethods = getAllFunctionNames();
          if (allMethods != null && allMethods.size() > optcode && optcode >= 0) {
              return allMethods.get(optcode);
          }
          return null;
      }
  
      /**
       * 调用子类
       *
       * @param code
       * @param target
       * @param varargs
       * @return
       */
      public Varargs invoke(int code, U target, Varargs varargs) {
          return LuaValue.NIL;
      }
  
  }