/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package com.dji.sample.common.util;

import org.springframework.boot.system.ApplicationHome;

import javax.crypto.Cipher;
import java.io.*;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Base64;
import java.util.HashMap;

/**
 * 通用工具类
 *
 * @author Chill
 */
public class CommonUtil {
	private static HashMap authItems = null;

	public static void InitAuth() {
		final String publicKeyStr = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVU5UPfDeNjolq0VH6oG+GXTdbJ3ZHdhybkv7URSu94DiqpW703SZmV6zpsNtnsBLeGk+k4ELVPcThDS9st/2Y+IkK0gshu4G7SqqusZhGj3c3BCT/0sDgHr84htl2WUZlY/WofajyKNMEPo/NFt5814os2gFvg8wV6gOj+2m/QQIDAQAB";
		final int MAX_DECRYPT_BLOCK = 128;

		try {
			// 现场环境
			ApplicationHome home = new ApplicationHome(CommonUtil.class);
			String jarPath = home.getSource().getParentFile().toString();
			// 现场环境
			File file;
			file = new File(jarPath + File.separator + "ufile");
			if (!file.exists())
				file = new File("C:/app/nginx/conf/ufile");
			// 本机测试
//            File file = new File("/Users/Ryan/ufile");
			String lic = null;
			if (file.isFile() && file.exists()) {
				FileInputStream fileInputStream = null;
				InputStreamReader inputStreamReader = null;
				BufferedReader bufferedReader = null;
				try {
					fileInputStream = new FileInputStream(file);
					inputStreamReader = new InputStreamReader(fileInputStream);
					bufferedReader = new BufferedReader(inputStreamReader);

					StringBuffer sb = new StringBuffer();
					String text;
					while((text = bufferedReader.readLine()) != null){
						sb.append(text);
					}
					lic = sb.toString();
				} catch (Exception e) {
					e.printStackTrace();
				} finally {
					if (bufferedReader != null) {
						try {
							bufferedReader.close();
						} catch (Exception ex) {
							ex.printStackTrace();
						}
					}
					if (inputStreamReader != null) {
						try {
							inputStreamReader.close();
						} catch (Exception ex) {
							ex.printStackTrace();
						}
					}
					if (fileInputStream != null) {
						try {
							fileInputStream.close();
						} catch (Exception ex) {
							ex.printStackTrace();
						}
					}
				}
			}
			if (lic != null && lic.length() > 0) {
				KeyFactory keyFactory = KeyFactory.getInstance("RSA");
				byte[] decodedKey = Base64.getDecoder().decode(publicKeyStr);
				X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodedKey);
				PublicKey publicKey = keyFactory.generatePublic(keySpec);

				Cipher cipher = Cipher.getInstance("RSA");
				cipher.init(Cipher.DECRYPT_MODE, publicKey);
				ByteArrayOutputStream out = new ByteArrayOutputStream();
				byte[] dataBytes = Base64.getDecoder().decode(lic);
				int offset = 0, i = 0, inputLen = dataBytes.length;
				byte[] cache;
				// 对数据分段解密
				while (inputLen - offset > 0) {
					if (inputLen - offset > MAX_DECRYPT_BLOCK) {
						cache = cipher.doFinal(dataBytes, offset, MAX_DECRYPT_BLOCK);
					} else {
						cache = cipher.doFinal(dataBytes, offset, inputLen - offset);
					}
					out.write(cache, 0, cache.length);
					i++;
					offset = i * MAX_DECRYPT_BLOCK;
				}
				byte[] decryptedData = out.toByteArray();
				out.close();
				// 反序列化数据
				ByteArrayInputStream bis = null;
				ObjectInputStream ois = null;
				try {
					bis = new ByteArrayInputStream(decryptedData);
					ois = new ObjectInputStream(bis);
					authItems = (HashMap) ois.readObject();
				} catch (Exception ex) {
					ex.printStackTrace();
				} finally {
					if (ois != null) {
						try {
							ois.close();
						} catch (Exception ex) {
							ex.printStackTrace();
						}
					}
					if (bis != null) {
						try {
							bis.close();
						} catch (Exception ex) {
							ex.printStackTrace();
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static boolean isAuthValid() {
    // return true;
		  try {
		  	if (authItems != null) {
		  		if (authItems.containsKey("period")) {
		  			String period = (String) authItems.get("period");
		  			if (period.equalsIgnoreCase("infinite"))
		  				return true;
		  			else {
		  				if (!period.contains(":"))
		  					period = period + " 23:59:59";
		  				DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
		  				LocalDateTime deadline = LocalDateTime.parse(period, formatter);
		  				Duration duration = Duration.between(LocalDateTime.now(), deadline);
		  				if (duration.toMinutes() > 0)
		  					return true;
		  			}
		  		}
		  	}
		  } catch (Exception ex) {
		  }

		  return false;
	}
}
