package com.palacesun.masking.tools;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ObjectTool {
   public static void fieldCoty(Object source, Object target) throws Exception {
      Class sourceClass = source.getClass();
      Class targetClass = target.getClass();
      List<Field> sourceFields = getAllField(sourceClass);
      List<Field> targetFields = getAllField(targetClass);

      for(Field sourceField : sourceFields) {
         String name = sourceField.getName();
         Class type = sourceField.getType();
         String methodName = name.substring(0, 1).toUpperCase() + name.substring(1);
         Method getMethod = sourceClass.getMethod("get" + methodName);
         Object value = getMethod.invoke(source);

         for(Field targetField : targetFields) {
            String targetName = targetField.getName();
            if (targetName.equals(name)) {
               Method setMethod = targetClass.getMethod("set" + methodName, type);
               setMethod.invoke(target, value);
               break;
            }
         }
      }

   }

   public static List listConvert(List source, Class targetClass) throws Exception {
      List target = new ArrayList();
      Constructor constructor = targetClass.getDeclaredConstructor();

      for(Object object : source) {
         Object temp = constructor.newInstance();
         fieldCoty(object, temp);
         target.add(temp);
      }

      return target;
   }

   public static byte[] input2byte(InputStream inStream) throws IOException {
      ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
      byte[] buff = new byte[100];
      int rc = 0;

      while((rc = inStream.read(buff, 0, 100)) > 0) {
         swapStream.write(buff, 0, rc);
      }

      byte[] in2b = swapStream.toByteArray();
      return in2b;
   }

   public static Map<String, String> getObjectFieldValue(Object obj) throws Exception {
      Map<String, String> map = new HashMap();
      Field[] fields = obj.getClass().getDeclaredFields();
      Field field = null;

      for(int i = 0; i < fields.length; ++i) {
         field = fields[i];
         field.setAccessible(true);
         if (field.get(obj) != null) {
            map.put(field.getName(), field.get(obj).toString());
         } else {
            map.put(field.getName(), "");
         }
      }

      return map;
   }

   public static Object getObjectByMap(Class c, Map<String, Object> map) {
      Object o = null;

      try {
         o = c.newInstance();

         List<Field> fieldList;
         for(fieldList = new ArrayList(); c != null; c = c.getSuperclass()) {
            fieldList.addAll(new ArrayList(Arrays.asList(c.getDeclaredFields())));
         }

         Field[] fields = new Field[fieldList.size()];
         fields = (Field[])fieldList.toArray(fields);

         for(Field field : fields) {
            if (map.get(field.getName()) != null) {
               Object value = map.get(field.getName());
               field.setAccessible(true);
               field.set(o, value);
            }
         }
      } catch (Exception e) {
         e.printStackTrace();
      }

      return o;
   }

   public static void setObjectFieldByMap(Object bean, Map<String, Object> map) throws Exception {
      if (bean != null) {
         for(Map.Entry<String, Object> item : map.entrySet()) {
            String field = (String)item.getKey();
            Object fieldvalue = item.getValue();
            String setfieldmethod = "set" + field.substring(0, 1).toUpperCase() + field.substring(1);
            Method m = bean.getClass().getMethod(setfieldmethod);
            if (fieldvalue != null) {
               m.invoke(bean, fieldvalue);
            }
         }

      }
   }

   public static List<Field> getAllField(Class c) {
      List<Field> list = new ArrayList();
      list.addAll(Arrays.asList(c.getDeclaredFields()));

      for(Class sc = c.getSuperclass(); !sc.getName().equals("java.lang.Object"); sc = sc.getSuperclass()) {
         list.addAll(Arrays.asList(sc.getDeclaredFields()));
      }

      return list;
   }

   public static Object callObjectMethod(Class objClass, Method method, Object... args) {
      if (objClass != null && method != null) {
         Object result = null;

         try {
            Object obj = objClass.newInstance();
            result = method.invoke(obj, args);
         } catch (Exception e) {
            e.printStackTrace();
         }

         return result;
      } else {
         return null;
      }
   }

   public static Method getObjectMethod(Class objClass, String methodName, Class... argsClass) {
      if (objClass != null && methodName != null && !"".equals(methodName.trim())) {
         Method m = null;

         try {
            m = objClass.getMethod(methodName, argsClass);
         } catch (Exception e) {
            e.printStackTrace();
         }

         return m;
      } else {
         return null;
      }
   }
}
