package com.aip.gateway.api.utils;

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

public final class SysUtils
{
    public static int toInt(String paramVal, int defVal) {
    	int result = defVal;
    	try {
    		result = Integer.parseInt(paramVal);
    	} catch(Exception e) {
    	}
    	return result;
    }

    public static float toFloat(String paramVal, float defVal) {
    	float result = defVal;
    	try {
    		result = Float.parseFloat(paramVal);
    	} catch(Exception e) {
    	}
    	return result;
    }
    
    public static double toDouble(String paramVal, double defVal) {
    	double result = defVal;
    	try {
    		result = Double.parseDouble(paramVal);
    	} catch(Exception e) {
    	}
    	return result;
    }

	public static String getSysTime()
	{
		SimpleDateFormat sdfDate = new SimpleDateFormat("yyyyMMddHHmmss");
		Date dtLog = new Date();
		return sdfDate.format(dtLog);
	}
	public static String getSysTimeStr() {
		SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date dtLog = new Date();
		return sdfDate.format(dtLog);
	}
	public static String getSysTimeStrMMDD() {
		SimpleDateFormat sdfDate = new SimpleDateFormat("MM-dd HH:mm:ss");
		Date dtLog = new Date();
		return sdfDate.format(dtLog);
	}

	public static int gapTime(String startTm, String endTm, int calcType) {

		if (startTm == null || startTm.equals("") || startTm.length() != 14) {
			return -1;
		}
		if (endTm == null || endTm.equals("") || endTm.length() != 14) {
			return -1;
		}

		Date startDateTime, endDateTime;
/*
		FastDateFormat fastDateFormat = FastDateFormat.getInstance("yyyyMMddHHmmss", new Locale("ko_KR")); //Locale.getDefault());
		try {
			startDateTime = fastDateFormat.parse(startTm);
			endDateTime = fastDateFormat.parse(endTm);
		} catch (ParseException e) {
			e.printStackTrace();
			return -1;
		}
*/
		startDateTime = TimeUtils.stringToDate(startTm);
		endDateTime = TimeUtils.stringToDate(endTm);
		if (startDateTime == null || endDateTime == null) {
			return -1;
		}

		GregorianCalendar gcStartDateTime = new GregorianCalendar();
		GregorianCalendar gcEndDateTime = new GregorianCalendar();
		gcStartDateTime.setTime(startDateTime);
		gcEndDateTime.setTime(endDateTime);

		long gap = gcEndDateTime.getTimeInMillis() - gcStartDateTime.getTimeInMillis();
		long hour = gap / 1000L / 60L / 60L;
		long min = gap / 1000L / 60L;
		long second = gap / 1000L;
		if (Calendar.HOUR == calcType)
			return (int)hour;
		if (Calendar.MINUTE == calcType)
			return (int)min;
		if (Calendar.SECOND == calcType)
			return (int)second;
		return -1;
	}

	public static byte[] stringToByteArr(String text) {
		//return text.getBytes(StandardCharsets.UTF_8);
		try {
			return text.getBytes("EUC_KR");
		} catch (UnsupportedEncodingException e) {
			return text.getBytes();
		}
	}
	public static byte[] stringToByteArray(String data) {
		//return data.getBytes();
		return data.getBytes(StandardCharsets.UTF_8);
	}
	public static void copyStringToByteArray(byte[] dest, int length, String data) {
		//byte[] byteData = data.getBytes();
		byte[] byteData = data.getBytes(StandardCharsets.UTF_8);
		int size = dest.length;
		int ii;
		for (ii = 0; ii < byteData.length && ii < size; ii++) {
			dest[ii] = byteData[ii];
		}
		for (int jj = ii; jj < size; jj++) {
			dest[jj] = 0x00;
		}
	}

	public static String byteArrayToString(byte[] data) {
		StringBuilder sb = new StringBuilder(data.length);
		for (int ii = 0; ii < data.length; ++ ii) {
			if (data[ii] >= 0x21 && data[ii] <= 0x7E) {
				sb.append((char) data[ii]);
			}
			else {
				break;
			}
		}
		return sb.toString();
	}

	public static String byteArrayToHex(byte[] AData) {
		if ((AData == null) || (AData.length == 0)) {
			return "";
		}

		int ALen = AData.length;
		int line = ALen / 16;
		int pos;

		StringBuffer sb = new StringBuffer((ALen*3)+line);
		sb.append("\r\n");
		for (int ii = 0; ii < ALen; ii += 16)
		{
			for (int jj = 0; jj < 16; jj++) {
				pos = ii + jj;
				if (pos < ALen) {
					String hexNumber = "0" + Integer.toHexString(0xFF & AData[pos]).toUpperCase();
					sb.append(hexNumber.substring(hexNumber.length() - 2));
					sb.append(" ");
				}
				else {
					break;
				}
			}
			sb.append("\r\n");
		}
		return sb.toString();
	}

	public static boolean isPrint(int c) {
		if ( c >= 0x20 && c <= 0x7e )
			return true;
		return false;
	}

	public static String byteArrayToHexAscii(byte[] AData) {
		if ((AData == null) || (AData.length == 0)) {
			return "";
		}

		int ALen = AData.length;
		int line = ALen / 16;
		int pos;

		StringBuffer sb = new StringBuffer((ALen*3)+line);
		sb.append("\r\n");
		for (int ii = 0; ii < ALen; ii += 16)
		{
			String ascii = "";
			for (int jj = 0; jj < 16; jj++) {
				pos = ii + jj;
				if (pos < ALen) {
					String hexNumber = "0" + Integer.toHexString(0xFF & AData[pos]).toUpperCase();
					sb.append(hexNumber.substring(hexNumber.length() - 2));
					sb.append(" ");
					int c = 0xFF & AData[pos];
					if (isPrint(c)) {
						ascii += String.format("%c", c);
					}
					else {
						ascii += ".";
					}
				}
				else {
					break;
				}
			}
			sb.append("      ;");
			sb.append(ascii);
			sb.append("\r\n");
		}
		return sb.toString();
	}

	public static int getBitValue(byte b, int pos) {
		int val = (b >> pos) & 0x01;
		return val;
	}

	public static long ipToLong(String ipAddress) {
		String[] ipAddressInArray = ipAddress.split("\\.");
		long result = 0;
		for (int i = 0; i < ipAddressInArray.length; i++) {
			int power = 3 - i;
			int ip = Integer.parseInt(ipAddressInArray[i]);
			result += ip * Math.pow(256, power);
		}
		return result;
	}
	public static long ipToLong2(String ipAddress) {
		long result = 0;
		String[] ipAddressInArray = ipAddress.split("\\.");

		for (int i = 3; i >= 0; i--) {
			long ip = Long.parseLong(ipAddressInArray[3 - i]);
			//left shifting 24,16,8,0 and bitwise OR
			//1. 192 << 24
			//1. 168 << 16
			//1. 1   << 8
			//1. 2   << 0
			result |= ip << (i * 8);
		}
		return result;
	}
	public static String longToIp(long i) {

		return ((i >> 24) & 0xFF) +
				"." + ((i >> 16) & 0xFF) +
				"." + ((i >> 8) & 0xFF) +
				"." + (i & 0xFF);

	}
	public static String longToIp2(long ip) {
		StringBuilder sb = new StringBuilder(15);

		for (int i = 0; i < 4; i++) {
			// 1. 2
			// 2. 1
			// 3. 168
			// 4. 192
			sb.insert(0, Long.toString(ip & 0xff));

			if (i < 3) {
				sb.insert(0, '.');
			}
			// 1. 192.168.1.2
			// 2. 192.168.1
			// 3. 192.168
			// 4. 192
			ip = ip >> 8;

		}

		return sb.toString();
	}

	public static int bytesToInt(byte[] bytes) {
		return ByteBuffer.wrap(bytes).getInt();
	}
	public static int bytesToInt(byte[] bytes, int fromIdx, ByteOrder byteOrder) {

		if (byteOrder == ByteOrder.BIG_ENDIAN) {
			return (
					((bytes[fromIdx+0] & 0xFF) << 24) |
					((bytes[fromIdx+1] & 0xFF) << 16) |
					((bytes[fromIdx+2] & 0xFF) << 8 ) |
					((bytes[fromIdx+3] & 0xFF) << 0 )
			);
		}
		return (
				((bytes[fromIdx+3] & 0xFF) << 24) |
				((bytes[fromIdx+2] & 0xFF) << 16) |
				((bytes[fromIdx+1] & 0xFF) << 8 ) |
				((bytes[fromIdx+0] & 0xFF) << 0 )
		);
	}
	public static byte[] intToBytes(int value) {
		// BIG_ENDIAN
		return  ByteBuffer.allocate(4).putInt(value).array();
	}

	public static int bytesToShort(byte[] bytes) {
		return ByteBuffer.wrap(bytes).getShort();
	}
	public static int bytesToShort(byte[] bytes, int fromIdx, ByteOrder byteOrder) {

		if (byteOrder == ByteOrder.BIG_ENDIAN) {
			return (
					((bytes[fromIdx+0] & 0xFF) << 8) |
					((bytes[fromIdx+1] & 0xFF) << 0 )
			);
		}
		return (
				((bytes[fromIdx+1] & 0xFF) << 8 ) |
				((bytes[fromIdx+0] & 0xFF) << 0 )
		);
	}
	public static byte[] shortToBytes(short value) {
		// BIG_ENDIAN
		return  ByteBuffer.allocate(2).putShort(value).array();
	}
}
