package cn.util.core;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.StringTokenizer;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import cn.constant.CharsetKit;

/**
 * 类型转换器
 */
public class TypeKit 
{
	/**转换Object[] 等格式值为由逗号分割的字符串*/
	public static String arrayToStr(Object... arg) 
	{
		String[] strings = Arrays.stream(arg).map(Object::toString).toArray(String[]::new);
		return String.join(",", strings);
	}

	/**
	 * 将List<String>集合 转化为带引号的String
	 * 如{"1","2"} To '1','2'
	 * 用于：SQL语句的 IN 子句 
	 */
	public static String listToStr(List<String> strList) {
		StringBuffer sb = new StringBuffer();
		if (IsKit.isNotNullOrEmpty(strList)) 
		{
			for (int i = 0,loop = strList.size(); i < loop; i++) {
				if (i == 0) {
					sb.append("'").append(strList.get(i)).append("'");
				} else {
					sb.append(",").append("'").append(strList.get(i)).append("'");
				}
			}
		}
		return sb.toString();
	}
	/**
	 * 将"1,2,3,..."这种形式的字符串转成"'1','2','3',..."这种形式
	 */
	public static String strToStr(String strs) 
	{
		if (IsKit.isNotNullOrEmpty(strs))
		{
			String[] idStrs = strs.trim().split(",");
			if (idStrs.length > 0) {
				StringBuffer sbf = new StringBuffer("");
				for (String str : idStrs) {
					if (IsKit.isNotBlank(str)) {
						sbf.append("'").append(str.trim()).append("'").append(",");
					}
				}
				if (sbf.length() > 0) {
					sbf = sbf.deleteCharAt(sbf.length() - 1);
					return sbf.toString();
				}
			}
		}
		return "";
	}
	/**
	 * 将"1,2,3,..."这种形式的字符串转成List<String> 集合
	 */
	public static List<String> strToList(String strs) 
	{
		if (IsKit.isNotNullOrEmpty(strs)){
			String[] idStrs = strs.trim().split(",");
			if (idStrs.length > 0) {
				List<String> strsList = new ArrayList<String>();
				for (String str : idStrs) {
					if (IsKit.isNotBlank(str)) {
						strsList.add(str.trim());
					}
				}
				if (strsList.size() > 0) {
					return strsList;
				}
			}
		}
		return null;
	}


	@SuppressWarnings("unchecked")
	public static <T> T cast(Object obj) {
		return (T) obj;
	}

	/*功能：将List<Object>转换为对应的List<具体类>
	 * TypeConvert.castList(list,Map.class) 转成list<map>
	 * */
	public static <T extends Object> List<T> castList(List<Object> list, Class<T> clazz)
	{
		List<T> arrayList = new ArrayList<T>();
		if (IsKit.isNotNull(list))
		{
			int size = list.size();
			for (int i=0;i<size;i++){
				arrayList.add(clazz.cast(list.get(i)));
			}
		}
		return arrayList;
	}
	/**
	 * List<Student> students = castList(result.get("out_refcursor"), Student.class);
	 */
	public static <T> List<T> castList(Object obj, Class<T> clazz)
	{
		List<T> result = new ArrayList<T>();
		if(obj instanceof List<?>) {
			for (Object o : (List<?>) obj)   {
				result.add(clazz.cast(o));
			}
			return result;
		}
		return null;
	}

	//创建Optional对象，差别在于of不允许参数是null，而ofNullable则无限制
	public static String objToStr(Object obj) 
	{//空字符
		return Optional.ofNullable(obj).map(Object::toString).orElse("");//null
	}
	public static Boolean objToBoolean(Object obj) 
	{
		String strValue = Optional.ofNullable(obj).map(Object::toString).orElse("false");
		return Boolean.parseBoolean(strValue);
	}
	public static Short objToShort(Object obj) 
	{
		String strValue = Optional.ofNullable(obj).map(Object::toString).orElse("0");
		return Short.parseShort(strValue);
	}
	public static Integer objToInt(Object obj) 
	{
		String strValue = Optional.ofNullable(obj).map(Object::toString).orElse("0");
		return  Integer.parseInt(strValue);
	}
	public static Long objToLong(Object obj) 
	{
		String strValue = Optional.ofNullable(obj).map(Object::toString).orElse("0L");
		return  Long.valueOf(strValue);
	}
	public static long objTolong(Object obj) 
	{
		return  objToLong(obj).longValue();
	}
	public static Double objToDouble(Object obj) 
	{
		String strValue = Optional.ofNullable(obj).map(Object::toString).orElse("0.0");
		return  Double.parseDouble(strValue);
	}
	public static Float objToFloat(Object obj) 
	{
		String strValue = Optional.ofNullable(obj).map(Object::toString).orElse("0.0");
		return Float.valueOf(strValue);
	}
	public static BigInteger objToBigInteger(Object obj) 
	{
		String strValue = Optional.ofNullable(obj).map(Object::toString).orElse("0.0");
		return new BigInteger(String.valueOf(strValue));
	}

	public static BigDecimal objToBigDecimal(Object obj) 
	{
		String strValue = Optional.ofNullable(obj).map(Object::toString).orElse("0.0");
		return  BigDecimal.valueOf(Double.parseDouble(strValue));
	}

	public String[] intArrayToStrArray(int[] intArray) {
		if (IsKit.isNullOrEmpty(intArray)) {
			return null;
		}
		String[] str = new String[intArray.length];
		for (int i = 0; i < intArray.length; i++) {
			str[i] = "" + intArray[i];
		}
		return str;
	}
	/**Integer.toString(a)等同于a.toString();
	 * String.valueOf(Object obj)可以把整型（包括0）转化为字符串，但是Integer如果是null的话，会转化为”null”
	 * */
	public static String intToStr(Object temp)//原来是int
	{   
		//当Integer是null的情况下，String是null，2020
		return (temp == null) ? null :temp.toString();
	}

	public static Optional<Integer> strToInt(String s) 
	{
		try {
			return Optional.of(Integer.parseInt(s));//如果String能转换为对应的Integer，将其封装在Optioal对象中返回
		} catch (NumberFormatException e) {
			return Optional.empty();//否则返回一个空的Optional对象
		}
	}

	/**
	 * 将字符串分解成字符串数组
	 * @param str 待分解的字符串
	 * @param token 分隔符，如："|"、","、"."、"---"、" "等
	 * @return 返回字符串数组
	 */
	public static String[] strToArray(String str, String token) 
	{
		if(IsKit.isNullOrEmpty(str)) {
			return null;
		}
		String[] ss = new String[0];
		List<String> a = new ArrayList<String>();
		StringTokenizer st = new StringTokenizer(str, token);
		while (st.hasMoreTokens()) {
			a.add(st.nextElement().toString());
		}
		if (a.size() > 0) {
			ss = new String[a.size()];
			for (int i = 0; i < ss.length; i++) {
				ss[i] = a.get(i).toString();
			}
		}
		return ss;
	}
	public static String[] arryToArray(String[] list, String l, String r) {

		if(IsKit.isNullOrEmpty(list))
		{
			return null;
		}
		String s = null;
		for (int i = 0; i < list.length; i++) {
			s = l + list[i] + r;
			list[i] = s;
		}
		return list;
	}
	public static String arryToStr(Object[] list, String linkop) 
	{
		String s = null;
		if (IsKit.isNotNullOrEmpty(list)) {
			s = objToStr(list[0]);
			if (list.length > 1) {
				for (int i = 1,loop = list.length; i < loop; i++) {
					s = s + linkop + list[i];
				}
			}
		}
		return s;
	}
	//Long 数组转为逗号分割的字符串
	public static String numArrayToStr(Long... arr) 
	{
		String[] x = Arrays.stream(arr).map(String::valueOf).toArray(String[]::new);
		return Arrays.stream(x).collect(Collectors.joining(","));
	}
	//数字字符串
	public static String numArrayToStr(String... arr) 
	{
		return Arrays.stream(arr).collect(Collectors.joining(","));
	}

	/**
	 * 转换为字符串<br>
	 * 如果给定的值为null，或者转换失败，返回默认值<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @param defaultValue 转换错误时的默认值
	 * @return 结果
	 */
	public static String toStr(Object value, String defaultValue)
	{
		if (null == value)
		{
			return defaultValue;
		}
		if (value instanceof String)
		{
			return (String) value;
		}
		return value.toString();
	}


	/**
	 * 转换为字符串<br>
	 * 如果给定的值为<code>null</code>，或者转换失败，返回默认值<code>null</code><br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @return 结果
	 */
	public static String toStr(Object value)
	{
		return toStr(value, null);
	}

		/**
	 * 将对象转为字符串<br>
	 * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法
	 *
	 * @param obj 对象
	 * @param charset 字符集
	 * @return 字符串
	 */
	public static String str(Object obj, Charset charset)
	{
		if (null == obj)
		{
			return null;
		}

		if (obj instanceof String)
		{
			return (String) obj;
		}
		else if (obj instanceof byte[] || obj instanceof Byte[])
		{
			return str((Byte[]) obj, charset);
		}
		else if (obj instanceof ByteBuffer)
		{
			return str((ByteBuffer) obj, charset);
		}
		return obj.toString();
	}
	/**
	 * 转换为int<br>
	 * 如果给定的值为空，或者转换失败，返回默认值<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @param defaultValue 转换错误时的默认值
	 * @return 结果
	 */
	public static Integer toInt(Object value, Integer defaultValue)
	{
		if (value == null)
		{
			return defaultValue;
		}
		if (value instanceof Integer)
		{
			return (Integer) value;
		}
		if (value instanceof Number)
		{
			return ((Number) value).intValue();
		}
		final String valueStr = toStr(value, null);
		if (StringUtils.isEmpty(valueStr))
		{
			return defaultValue;
		}
		try
		{
			return Integer.parseInt(valueStr.trim());
		}
		catch (Exception e)
		{
			return defaultValue;
		}
	}

	/**
	 * 转换为int<br>
	 * 如果给定的值为<code>null</code>，或者转换失败，返回默认值<code>null</code><br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @return 结果
	 */
	public static Integer toInt(Object value)
	{
		return toInt(value, null);
	}
	

	/**
	 * 转换为long<br>
	 * 如果给定的值为空，或者转换失败，返回默认值<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @param defaultValue 转换错误时的默认值
	 * @return 结果
	 */
	public static Long toLong(Object value, Long defaultValue)
	{
		if (value == null)
		{
			return defaultValue;
		}
		if (value instanceof Long)
		{
			return (Long) value;
		}
		if (value instanceof Number)
		{
			return ((Number) value).longValue();
		}
		final String valueStr = toStr(value, null);
		if (StringUtils.isEmpty(valueStr))
		{
			return defaultValue;
		}
		try
		{
			// 支持科学计数法
			return new BigDecimal(valueStr.trim()).longValue();
		}
		catch (Exception e)
		{
			return defaultValue;
		}
	}

	/**
	 * 转换为long<br>
	 * 如果给定的值为<code>null</code>，或者转换失败，返回默认值<code>null</code><br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @return 结果
	 */
	public static Long toLong(Object value)
	{
		return toLong(value, null);
	}

	/**
	 * 转换为double<br>
	 * 如果给定的值为空，或者转换失败，返回默认值<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @param defaultValue 转换错误时的默认值
	 * @return 结果
	 */
	public static Double toDouble(Object value, Double defaultValue)
	{
		if (value == null)
		{
			return defaultValue;
		}
		if (value instanceof Double)
		{
			return (Double) value;
		}
		if (value instanceof Number)
		{
			return ((Number) value).doubleValue();
		}
		final String valueStr = toStr(value, null);
		if (StringUtils.isEmpty(valueStr))
		{
			return defaultValue;
		}
		try
		{
			// 支持科学计数法
			return new BigDecimal(valueStr.trim()).doubleValue();
		}
		catch (Exception e)
		{
			return defaultValue;
		}
	}

	/**
	 * 转换为double<br>
	 * 如果给定的值为空，或者转换失败，返回默认值<code>null</code><br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @return 结果
	 */
	public static Double toDouble(Object value)
	{
		return toDouble(value, null);
	}

	/**
	 * 转换为Float<br>
	 * 如果给定的值为空，或者转换失败，返回默认值<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @param defaultValue 转换错误时的默认值
	 * @return 结果
	 */
	public static Float toFloat(Object value, Float defaultValue)
	{
		if (value == null)
		{
			return defaultValue;
		}
		if (value instanceof Float)
		{
			return (Float) value;
		}
		if (value instanceof Number)
		{
			return ((Number) value).floatValue();
		}
		final String valueStr = toStr(value, null);
		if (StringUtils.isEmpty(valueStr))
		{
			return defaultValue;
		}
		try
		{
			return Float.parseFloat(valueStr.trim());
		}
		catch (Exception e)
		{
			return defaultValue;
		}
	}

	/**
	 * 转换为Float<br>
	 * 如果给定的值为空，或者转换失败，返回默认值<code>null</code><br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @return 结果
	 */
	public static Float toFloat(Object value)
	{
		return toFloat(value, null);
	}

	/**
	 * 转换为boolean<br>
	 * String支持的值为：true、false、yes、ok、no，1,0 如果给定的值为空，或者转换失败，返回默认值<br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @param defaultValue 转换错误时的默认值
	 * @return 结果
	 */
	public static Boolean toBool(Object value, Boolean defaultValue)
	{
		if (value == null)
		{
			return defaultValue;
		}
		if (value instanceof Boolean)
		{
			return (Boolean) value;
		}
		String valueStr = toStr(value, null);
		if (StringUtils.isEmpty(valueStr))
		{
			return defaultValue;
		}
		valueStr = valueStr.trim().toLowerCase();
		switch (valueStr)
		{
		case "true":
			return true;
		case "false":
			return false;
		case "yes":
			return true;
		case "ok":
			return true;
		case "no":
			return false;
		case "1":
			return true;
		case "0":
			return false;
		default:
			return defaultValue;
		}
	}

	/**
	 * 转换为boolean<br>
	 * 如果给定的值为空，或者转换失败，返回默认值<code>null</code><br>
	 * 转换失败不会报错
	 *
	 * @param value 被转换的值
	 * @return 结果
	 */
	public static Boolean toBool(Object value)
	{
		return toBool(value, null);
	}

	/**
	 * 将对象转为字符串<br>
	 * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法
	 *
	 * @param obj 对象
	 * @return 字符串
	 */
	public static String utf8ToStr(Object obj)
	{
		return str(obj, CharsetKit.CHARSET_UTF_8);
	}
}

