/**
 * Copyright (c)  2014-2020 Gaoxiaobang, Inc.
 * All rights reserved.
 * <p>
 * This software is the confidential and proprietary information of Gaoxiaobang,
 * Inc. ("Confidential Information"). You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into with Gaoxiaobang.
 */
package com.energy.manage.common.util;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConversionException;
import org.apache.commons.beanutils.PropertyUtils;

import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;


/**
 * @author lh
 * @date 2015年10月29日
 */
public class BeanTools {
  private static char UNDERLINE = 95;

  public static void populate(Object bean, Map<String, ? extends Object> properties) {
    try {
      BeanUtils.populate(bean, toReplaceKeyLow(properties));
    } catch (IllegalAccessException e1) {
      ExceptionTools.unchecked(e1);
    } catch (InvocationTargetException e2) {
      ExceptionTools.unchecked(e2);
    }
  }

  /**
   * 替换驼峰Map
   * * @param map
   *
   * @return
   */
  public static Map<String, Object> toReplaceKeyLow(Map<String, ? extends Object> map) {
    Map re_map = new HashMap();
    if (re_map != null) {
      Iterator var2 = map.entrySet().iterator();
      while (var2.hasNext()) {
        Map.Entry<String, Object> entry = (Map.Entry) var2.next();
        re_map.put(underlineToCamel(entry.getKey()), map.get(entry.getKey()));
      }
      map.clear();
    }
    return re_map;
  }

  public static String underlineToCamel(String param) {
    if (param == null || "".equals(param.trim())) {
      return "";
    }
    int len = param.length();
    StringBuilder sb = new StringBuilder(len);
    for (int i = 0; i < len; i++) {
      char c = param.charAt(i);
      if (c == UNDERLINE) {
        if (++i < len) {
          sb.append(Character.toUpperCase(param.charAt(i)));
        }
      } else {
        sb.append(c);
      }
    }
    return sb.toString();
  }


  public static void copyProperties(Object to, Object from) {
    try {
      BeanUtils.copyProperties(to, from);
    } catch (ConversionException e1) {
      ExceptionTools.unchecked(e1);
    } catch (IllegalAccessException e2) {
      ExceptionTools.unchecked(e2);
    } catch (InvocationTargetException e3) {
      ExceptionTools.unchecked(e3);
    }
  }

  public static void copyProperty(Object bean, String name, Object value) {
    try {
      BeanUtils.copyProperty(bean, name, value);
    } catch (ConversionException e1) {
      ExceptionTools.unchecked(e1);
    } catch (IllegalAccessException e2) {
      ExceptionTools.unchecked(e2);
    } catch (InvocationTargetException e3) {
      ExceptionTools.unchecked(e3);
    }
  }

  public static void setProperty(Object obj, String name, Object value) {
    try {
      BeanUtils.setProperty(obj, name, value);
    } catch (IllegalAccessException e1) {
      ExceptionTools.unchecked(e1);
    } catch (InvocationTargetException e2) {
      ExceptionTools.unchecked(e2);
    }
  }

  public static String getProperty(Object obj, String name) {
    try {
      return BeanUtils.getProperty(obj, name);
    } catch (InvocationTargetException e1) {
      ExceptionTools.unchecked(e1);
    } catch (IllegalAccessException e2) {
      ExceptionTools.unchecked(e2);
    } catch (NoSuchMethodException e3) {
      ExceptionTools.unchecked(e3);
    }
    return null;
  }

  public static boolean equalProperty(Object obj, String name, Object value) {
    return StringTools.getString(value).equals(getProperty(obj, name));
  }


  public static <T> List<T> listPopulate(List<Map> list, Class<T> clazz) throws RuntimeException {
    List t = new ArrayList<T>();
    try {
      for (Map map : list) {
        T bean = null;
        bean = clazz.newInstance();
        BeanUtils.populate(bean, map);
        t.add(bean);
      }
      return t;
    } catch (Exception e) {
      throw ExceptionTools.unchecked(e);
    }
  }

  public static void copyNotNullProperties(Object to, Object from) {

    PropertyDescriptor[] propertyDescriptors = PropertyUtils.getPropertyDescriptors(to);
    try {
      for (PropertyDescriptor descriptor : propertyDescriptors) {

        Method write = PropertyUtils.getWriteMethod(descriptor);
        Method read = PropertyUtils.getReadMethod(descriptor);
        if (write == null || read == null) {
          continue;
        }

        String property = descriptor.getName();

        try {
          Object value = PropertyUtils.getProperty(from, property);
          if (value != null) {
            PropertyUtils.setProperty(to, property, value);
          }
        } catch (NoSuchMethodException e) {

        }

      }
    } catch (InvocationTargetException e1) {
      ExceptionTools.unchecked(e1);
    } catch (IllegalAccessException e2) {

    }
  }

}
