package com.ygtx.emcs.util;

import android.util.Log;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by yy-01 on 2015/4/23. 描述：字符串处理
 */
public class StringUtils {

	/**
	 * 描述：将null转化为“”.
	 * 
	 * @param str
	 *            指定的字符串
	 * @return 字符串的String类型
	 */
	public static String parseEmpty(String str) {
		if (str == null || "null".equals(str.trim())) {
			str = "";
		}
		return str.trim();
	}

	/**
	 * 字符串是否为空（会排除字符串左右空格）
	 *
	 * @param source
	 * @return
	 */
	public static boolean isEmptyStr(String source) {
		if (source == null || source.trim().length() == 0)
			return true;
		return false;
	}

	/**
	 * 描述：判断一个字符串是否为null或空值.
	 * 
	 * @param str
	 *            指定的字符串
	 * @return true or false
	 */
	public static boolean isEmpty(String str) {
		return str == null || str.trim().length() == 0;
	}

	/**
	 * 获取字符串中文字符的长度（每个中文算2个字符）.
	 * 
	 * @param str
	 *            指定的字符串
	 * @return 中文字符的长度
	 */
	public static int chineseLength(String str) {
		int valueLength = 0;
		String chinese = "[\u0391-\uFFE5]";
		/* 获取字段值的长度，如果含中文字符，则每个中文字符长度为2，否则为1 */
		if (!isEmpty(str)) {
			for (int i = 0; i < str.length(); i++) {
				/* 获取一个字符 */
				String temp = str.substring(i, i + 1);
				/* 判断是否为中文字符 */
				if (temp.matches(chinese)) {
					valueLength += 2;
				}
			}
		}
		return valueLength;
	}

	/**
	 * 描述：获取字符串的长度.
	 * 
	 * @param str
	 *            指定的字符串
	 * @return 字符串的长度（中文字符计2个）
	 */
	public static int strLength(String str) {
		int valueLength = 0;
		String chinese = "[\u0391-\uFFE5]";
		if (!isEmpty(str)) {
			// 获取字段值的长度，如果含中文字符，则每个中文字符长度为2，否则为1
			for (int i = 0; i < str.length(); i++) {
				// 获取一个字符
				String temp = str.substring(i, i + 1);
				// 判断是否为中文字符
				if (temp.matches(chinese)) {
					// 中文字符长度为2
					valueLength += 2;
				} else {
					// 其他字符长度为1
					valueLength += 1;
				}
			}
		}
		return valueLength;
	}

	/**
	 * 描述：获取指定长度的字符所在位置.
	 * 
	 * @param str
	 *            指定的字符串
	 * @param maxL
	 *            要取到的长度（字符长度，中文字符计2个）
	 * @return 字符的所在位置
	 */
	public static int subStringLength(String str, int maxL) {
		int currentIndex = 0;
		int valueLength = 0;
		String chinese = "[\u0391-\uFFE5]";
		// 获取字段值的长度，如果含中文字符，则每个中文字符长度为2，否则为1
		for (int i = 0; i < str.length(); i++) {
			// 获取一个字符
			String temp = str.substring(i, i + 1);
			// 判断是否为中文字符
			if (temp.matches(chinese)) {
				// 中文字符长度为2
				valueLength += 2;
			} else {
				// 其他字符长度为1
				valueLength += 1;
			}
			if (valueLength >= maxL) {
				currentIndex = i;
				break;
			}
		}
		return currentIndex;
	}

	/**
	 * 描述：手机号格式验证.
	 * 
	 * @param str
	 *            指定的手机号码字符串
	 * @return 是否为手机号码格式:是为true，否则false
	 */
	public static Boolean isMobileNo(String str) {
		Boolean isMobileNo = false;
		try {
			Pattern p = Pattern
					.compile("^((13[0-9])|(15[^4,\\D])|(18[0-9]))\\d{8}$");
			Matcher m = p.matcher(str);
			isMobileNo = m.matches();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return isMobileNo;
	}

	/**
	 * 电话号码验证
	 * @author ：shijing
	 * 2016年12月5日下午4:34:21
	 * @param  str
	 * @return 验证通过返回true
	 */
	public static boolean isPhone(final String str) {
		Pattern p1 = null, p2 = null;
		Matcher m = null;
		boolean b = false;
		p1 = Pattern.compile("^[0][1-9]{2,3}[0-9]{5,10}$");  // 验证带区号的
		p2 = Pattern.compile("^[1-9]{1}[0-9]{5,8}$");         // 验证没有区号的
		if (str.length() > 9) {
			m = p1.matcher(str);
			b = m.matches();
		} else {
			m = p2.matcher(str);
			b = m.matches();
		}
		return b;
	}
	/**
	 * 描述：是否只是字母和数字.
	 * 
	 * @param str
	 *            指定的字符串
	 * @return 是否只是字母和数字:是为true，否则false
	 */
	public static Boolean isNumberLetter(String str) {
		Boolean isNoLetter = false;
		String expr = "^[A-Za-z0-9]+$";
		if (str.matches(expr)) {
			isNoLetter = true;
		}
		return isNoLetter;
	}

	/**
	 * 描述：是否只是数字.
	 * 
	 * @param str
	 *            指定的字符串
	 * @return 是否只是数字:是为true，否则false
	 */
	public static Boolean isNumber(String str) {
		Boolean isNumber = false;
		String expr = "^[0-9]+$";
		if (str.matches(expr)) {
			isNumber = true;
		}
		return isNumber;
	}

	/**
	 * 描述：是否只是数字和逗号
	 *
	 * @param str
	 *            指定的字符串
	 * @return 是否只是数字:是为true，否则false
	 */
	public static Boolean isSplitNumber(String str) {
		Boolean isNumber = false;
		str = str.trim().replaceAll("\r\n","");
		String expr = "^(\\d+,)*\\d+$";
		if (str.matches(expr)) {
			isNumber = true;
		}
		return isNumber;
	}

	/**
	 * 描述：是否是邮箱.
	 * 
	 * @param str
	 *            指定的字符串
	 * @return 是否是邮箱:是为true，否则false
	 */
	public static Boolean isEmail(String str) {
		Boolean isEmail = false;
		String expr = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
		if (str.matches(expr)) {
			isEmail = true;
		}
		return isEmail;
	}

	/**
	 * 描述：是否是中文.
	 * 
	 * @param str
	 *            指定的字符串
	 * @return 是否是中文:是为true，否则false
	 */
	public static Boolean isChinese(String str) {
		Boolean isChinese = true;
		String chinese = "[\u0391-\uFFE5]";
		if (!isEmpty(str)) {
			// 获取字段值的长度，如果含中文字符，则每个中文字符长度为2，否则为1
			for (int i = 0; i < str.length(); i++) {
				// 获取一个字符
				String temp = str.substring(i, i + 1);
				// 判断是否为中文字符
				if (temp.matches(chinese)) {
				} else {
					isChinese = false;
				}
			}
		}
		return isChinese;
	}

	/**
	 * 描述：是否包含中文.
	 * 
	 * @param str
	 *            指定的字符串
	 * @return 是否包含中文:是为true，否则false
	 */
	public static Boolean isContainChinese(String str) {
		Boolean isChinese = false;
		String chinese = "[\u0391-\uFFE5]";
		if (!isEmpty(str)) {
			// 获取字段值的长度，如果含中文字符，则每个中文字符长度为2，否则为1
			for (int i = 0; i < str.length(); i++) {
				// 获取一个字符
				String temp = str.substring(i, i + 1);
				// 判断是否为中文字符
				if (temp.matches(chinese)) {
					isChinese = true;
				} else {

				}
			}
		}
		return isChinese;
	}

	/**
	 * 描述：从输入流中获得String.
	 * 
	 * @param is
	 *            输入流
	 * @return 获得的String
	 */
	public static String convertStreamToString(InputStream is) {
		BufferedReader reader = new BufferedReader(new InputStreamReader(is));
		StringBuilder sb = new StringBuilder();
		String line = null;
		try {
			while ((line = reader.readLine()) != null) {
				sb.append(line + "\n");
			}

			// 最后一个\n删除
			if (sb.indexOf("\n") != -1
					&& sb.lastIndexOf("\n") == sb.length() - 1) {
				sb.delete(sb.lastIndexOf("\n"), sb.lastIndexOf("\n") + 1);
			}

		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return sb.toString();
	}

	/**
	 * 描述：标准化日期时间类型的数据，不足两位的补0.
	 * 
	 * @param dateTime
	 *            预格式的时间字符串，如:2012-3-2 12:2:20
	 * @return String 格式化好的时间字符串，如:2012-03-20 12:02:20
	 */
	public static String dateTimeFormat(String dateTime) {
		StringBuilder sb = new StringBuilder();
		try {
			if (isEmpty(dateTime)) {
				return null;
			}
			String[] dateAndTime = dateTime.split(" ");
			if (dateAndTime.length > 0) {
				for (String str : dateAndTime) {
					if (str.indexOf("-") != -1) {
						String[] date = str.split("-");
						for (int i = 0; i < date.length; i++) {
							String str1 = date[i];
							sb.append(strFormat2(str1));
							if (i < date.length - 1) {
								sb.append("-");
							}
						}
					} else if (str.indexOf(":") != -1) {
						sb.append(" ");
						String[] date = str.split(":");
						for (int i = 0; i < date.length; i++) {
							String str1 = date[i];
							sb.append(strFormat2(str1));
							if (i < date.length - 1) {
								sb.append(":");
							}
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		return sb.toString();
	}

	/**
	 * 描述：不足2个字符的在前面补“0”.
	 * 
	 * @param str
	 *            指定的字符串
	 * @return 至少2个字符的字符串
	 */
	public static String strFormat2(String str) {
		try {
			if (str.length() <= 1) {
				str = "0" + str;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return str;
	}

	/**
	 * 描述：截取字符串到指定字节长度.
	 * 
	 * @param str
	 *            the str
	 * @param length
	 *            指定字节长度
	 * @return 截取后的字符串
	 */
	public static String cutString(String str, int length) {
		return cutString(str, length, "");
	}

	/**
	 * 描述：截取字符串到指定字节长度.
	 * 
	 * @param str
	 *            文本
	 * @param length
	 *            字节长度
	 * @param dot
	 *            省略符号
	 * @return 截取后的字符串
	 */
	public static String cutString(String str, int length, String dot) {
		int strBLen = strlen(str, "GBK");
		if (strBLen <= length) {
			return str;
		}
		int temp = 0;
		StringBuffer sb = new StringBuffer(length);
		char[] ch = str.toCharArray();
		for (char c : ch) {
			sb.append(c);
			if (c > 256) {
				temp += 2;
			} else {
				temp += 1;
			}
			if (temp >= length) {
				if (dot != null) {
					sb.append(dot);
				}
				break;
			}
		}
		return sb.toString();
	}

	/**
	 * 描述：截取字符串从第一个指定字符.
	 * 
	 * @param str1
	 *            原文本
	 * @param str2
	 *            指定字符
	 * @param offset
	 *            偏移的索引
	 * @return 截取后的字符串
	 */
	public static String cutStringFromChar(String str1, String str2, int offset) {
		if (isEmpty(str1)) {
			return "";
		}
		int start = str1.indexOf(str2);
		if (start != -1) {
			if (str1.length() > start + offset) {
				return str1.substring(start + offset);
			}
		}
		return "";
	}

	/**
	 * 描述：获取字节长度.
	 * 
	 * @param str
	 *            文本
	 * @param charset
	 *            字符集（GBK）
	 * @return the int
	 */
	public static int strlen(String str, String charset) {
		if (str == null || str.length() == 0) {
			return 0;
		}
		int length = 0;
		try {
			length = str.getBytes(charset).length;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return length;
	}

	/**
	 * 获取大小的描述.
	 * 
	 * @param size
	 *            字节个数
	 * @return 大小的描述
	 */
	public static String getSizeDesc(long size) {
		String suffix = "B";
		if (size >= 1024) {
			suffix = "K";
			size = size >> 10;
			if (size >= 1024) {
				suffix = "M";
				// size /= 1024;
				size = size >> 10;
				if (size >= 1024) {
					suffix = "G";
					size = size >> 10;
					// size /= 1024;
				}
			}
		}
		return size + suffix;
	}

	/**
	 * 描述：ip地址转换为10进制数.
	 * 
	 * @param ip
	 *            the ip
	 * @return the long
	 */
	public static long ip2int(String ip) {
		ip = ip.replace(".", ",");
		String[] items = ip.split(",");
		return Long.valueOf(items[0]) << 24 | Long.valueOf(items[1]) << 16
				| Long.valueOf(items[2]) << 8 | Long.valueOf(items[3]);
	}
	/**
	 * 产生序列号
	 * 
	 * @return
	 */
	public synchronized static Long getSeq() {
		Long seq = System.nanoTime();
		try {
			Thread.sleep(1);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		String idStr = seq.toString();
		int length = idStr.length();
		if (idStr.length() > 15) {
			idStr = idStr.substring(length - 15, length);
		}
		// System.out.println("原：" + idStr);
		return Long.parseLong(idStr);
	}
	/**
	 * 获取字符串内的数字，无任何格式(用以解析语音备忘时间)
	 * @param str 需要抽取数字的字符串
	 * @return 字符串内的数字
	 */
	public static int getNumFromString(String str) {
		String regEx="[^0-9]";   
		Pattern p = Pattern.compile(regEx);
		if(!str.equals("")||str.trim().length()!=0) { //字符串不能为空，否则返回“61”
			Matcher m = p.matcher(str); 
			if(!m.replaceAll("").trim().toString().equals("")||str.trim().length()!=0) {//字符串不能无数字，否则返回“61”
				int result = Integer.parseInt(m.replaceAll("").trim().toString());
				return result;
			} else {
				return 61;
			}
		} else {
			return 61;
		}
	}
	/**
	 * 将时间转化成 xx:xx格式 
	 * @param time 12:3 
	 * @return 12:03
	 */
	public static String timeFormat(String time) {
		String hour = time.substring(0, time.indexOf(":"));
		String minute = time.substring(time.indexOf(":")+1);
		try {
			if (hour.length() <= 1) {
				hour = "0" + hour;
			}
			if (minute.length() <= 1) {
				minute = "0" + minute;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return hour + ":" + minute;
	}
	
	public static String change2TimeFormat(String date) {
//		String temp_time = date.substring(date.indexOf("日")+1);
		String temp = date.replace("年", "-");
		temp = temp.replace("月", "-");
		temp = temp.replace("日", " ");
		temp = temp + ":0";
		String result = dateTimeFormat(temp);
		return result;
	}

	public static double getDouble(String value) {
		try {
			Double d = Double.valueOf(value);
			return d;
		} catch (NumberFormatException e) {
		}
		return 0;
	}

	public static float fix(float val, int fix) {
		String str = ""+val;
		NumberFormat nf = NumberFormat.getNumberInstance();
		nf.setMaximumFractionDigits(2);
		nf.setGroupingUsed(false);
		str = nf.format(Double.parseDouble(str));
		return Float.valueOf(str);
	}

	public static Double fix(Double val, int fix) {
		String str = ""+val;
		NumberFormat nf = NumberFormat.getNumberInstance();
		nf.setMaximumFractionDigits(2);
		nf.setGroupingUsed(false);
		str = nf.format(Double.parseDouble(str));
		return Double.valueOf(str);
	}

	public static String str2HexStr(String str)
	{
		char[] chars = "0123456789ABCDEF".toCharArray();
		StringBuilder sb = new StringBuilder("");
		byte[] bs = str.getBytes();
		int bit;

		for (byte b : bs) {
			bit = (b & 0x0f0) >> 4;
			sb.append(chars[bit]);
			bit = b & 0x0f;
			sb.append(chars[bit]);
		}
		return sb.toString().trim();
	}

	public static BigDecimal caclPerWeight(Integer qty,BigDecimal weight){
		if(weight==null){
			return BigDecimal.ZERO;
		}
		if(weight.floatValue()==0){
			return BigDecimal.ZERO;
		}
		if(qty==0){
			return BigDecimal.ZERO;
		}
		return weight.divide(new BigDecimal(qty),2,BigDecimal.ROUND_HALF_UP);
	}

	public static String getToday(){
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");// HH:mm:ss
		Date date = new Date(System.currentTimeMillis());
		String d = simpleDateFormat.format(date);
		return d;
	}

	public static String dateToStr(Date date,String format){
		if(date==null){
			return null;
		}
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
		String d = simpleDateFormat.format(date);
		return d;
	}

	public static String changeCode(String code){
		if(StringUtils.isEmpty(code)){
			return code;
		}
		if(code.length() == 10){
			code = code.substring(2);
			String ix = code.substring(0,3);
			String ex = code.substring(4,7);
			code = ix + "-" + ex;
		}
		return code;
	}

	/**
	 *
	 * @param lora 信道+组号+地址，6位数
	 * @return
	 */
	public static int getLora(String lora){
		if(StringUtils.isEmpty(lora)){
			return 0;
		}
		try {
			String sign = lora.substring(0, 2);
			String group = lora.substring(2, 4);
			String address = lora.substring(4);
			int s = Integer.valueOf(sign, 16);
			int g = Integer.valueOf(group, 16);
			int a = Integer.valueOf(address, 16);
			return s * 256 * 256 + g * 256 + a;
		}catch (Exception ex){
			ex.printStackTrace();
		}
		return 0;
	}
	public static Map<String,String> getLora(int robotNumber){
		String channelGroup = Integer.toHexString((robotNumber&0xFF0000)/(256*256));
		String loraGroup = Integer.toHexString((robotNumber&0x00FF00)/(256));
		String loraAddr = Integer.toHexString(robotNumber&0x0000FF).toUpperCase();
		channelGroup = channelGroup.length()<2?"0"+channelGroup:channelGroup;
		loraGroup = loraGroup.length()<2?"0"+loraGroup:loraGroup;
		loraAddr = loraAddr.length()<2?"0"+loraAddr:loraAddr;
		Map<String,String> resMap = new HashMap<>();
		resMap.put("channel_group",channelGroup);
		resMap.put("lora_group",loraGroup);
		resMap.put("lora_addr",loraAddr);
		return resMap;
	}

	public static String fixMac(String inMac) {
		final StringBuilder b = new StringBuilder(18);
		for (int i = 0; i < inMac.length(); i++) {
			b.append(inMac.charAt(i));
			if (i%2 == 1 && i != inMac.length()-1) b.append(':');
		}
		return b.toString();
	}

	public static boolean isOnline() {
		String result = null;
		try {
			String ip = "www.baidu.com";// ping 的地址，可以换成任何一种可靠的外网
			Process p = Runtime.getRuntime().exec("ping -c 1 -w 100 " + ip);// ping网址3次
			// 读取ping的内容，可以不加
			InputStream input = p.getInputStream();
			BufferedReader in = new BufferedReader(new InputStreamReader(input));
			StringBuilder stringBuffer = new StringBuilder();
			String content = "";
			while ((content = in.readLine()) != null) {
				stringBuffer.append(content);
			}
			// ping的状态
			int status = p.waitFor();
			if (status == 0) {
				result = "success";
				return true;
			} else {
				result = "failed";
			}
		} catch (IOException e) {
			result = "IOException";
		} catch (InterruptedException e) {
			result = "InterruptedException";
		} finally {
			Log.d("----result---", "result = " + result);
		}
		return false;
	}

	public static Integer addBytes(String data){
		int n = 0;
		if(StringUtils.isEmpty(data)){
			return null;
		}
		byte[] bytes = data.getBytes(StandardCharsets.UTF_8);
		for (byte b:bytes){
			n = n + b;
		}
		return n%65536;
	}

	public static void main(String[] arg) {
		String str = "1701A1";
		System.out.println(getLora(str));
	}
}
