package com.demo.util;


import com.demo.common.SpecialSecret;
import com.reyun.Algorithm;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URLEncoder;
import java.security.Key;
import java.util.Random;


/**
 *
 * 文件加密
 *
 */
public class FileEncryptor {


	private static final String ALGORITHM = "AES";
	private static final int CACHE_SIZE = 1024;

	/**
	 * <p>
	 * 文件加密
	 * </p>
	 *
	 * @param key
	 * @param sourceFilePath
	 * @param destFilePath
	 * @throws Exception
	 */
	public static void encryptFile(String key, String sourceFilePath, String destFilePath) throws Exception {
		File sourceFile = new File(sourceFilePath);
		File destFile = new File(destFilePath);
		if (sourceFile.exists() && sourceFile.isFile()) {
			if (!destFile.getParentFile().exists()) {
				destFile.getParentFile().mkdirs();
			}
			destFile.createNewFile();
			InputStream in = new FileInputStream(sourceFile);
			OutputStream out = new FileOutputStream(destFile);

			byte[] data = inputStreamToByte(in);
			byte[] aesData = SpecialSecret.aes256EncodeB(data, key.getBytes());
			ByteArrayInputStream cin = StringToInputStream(aesData);
//			byte[] raw = key.getBytes();
//			SecretKeySpec secretKeySpec = new SecretKeySpec(raw, ALGORITHM);
//			Cipher cipher = Cipher.getInstance(ALGORITHM);
//			cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
//			CipherInputStream cin = new CipherInputStream(in, cipher);
			byte[] cache = new byte[CACHE_SIZE];
			int nRead = 0;
			while ((nRead = cin.read(cache)) != -1) {
				out.write(cache, 0, nRead);
				out.flush();
			}
			out.close();
			cin.close();
			in.close();
		}
	}

	public static byte[] inputStreamToByte(InputStream input) throws IOException{
		byte[] b = new byte[4096];
		for (int n; (n = input.read(b)) != -1;) {
		}
		return b;
	}


	public static ByteArrayInputStream StringToInputStream(byte[] str){
		ByteArrayInputStream is = new ByteArrayInputStream(str);
		return is;
	}


	/**
	 * <p>
	 * 文件解密
	 * </p>
	 *
	 * @param key
	 * @param sourceFilePath
	 * @param destFilePath
	 * @throws Exception
	 */
	public static void decryptFile(String key, String sourceFilePath, String destFilePath) throws Exception {
		File sourceFile = new File(sourceFilePath);
		File destFile = new File(destFilePath);
		if (sourceFile.exists() && sourceFile.isFile()) {
			if (!destFile.getParentFile().exists()) {
				destFile.getParentFile().mkdirs();
			}
			destFile.createNewFile();
			FileInputStream in = new FileInputStream(sourceFile);
			FileOutputStream out = new FileOutputStream(destFile);
			byte[] raw = key.getBytes();
			SecretKeySpec secretKeySpec = new SecretKeySpec(raw, ALGORITHM);
			Cipher cipher = Cipher.getInstance(ALGORITHM);
			cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
			CipherOutputStream cout = new CipherOutputStream(out, cipher);
			byte[] cache = new byte[CACHE_SIZE];
			int nRead = 0;
			while ((nRead = in.read(cache)) != -1) {
				cout.write(cache, 0, nRead);
				cout.flush();
			}
			cout.close();
			out.close();
			in.close();
		}
	}

//	public static void downloadFileToPath(String sourceFilePath, String destFilePath) throws Exception{
//		   File sourceFile = new File(sourceFilePath);
//		   File destFile = new File(destFilePath);
//		   if (sourceFile.exists() && sourceFile.isFile()) {
//			   if (!destFile.getParentFile().exists()) {
//				   destFile.getParentFile().mkdirs();
//			   }
//			   destFile.createNewFile();
//			   FileInputStream in = new FileInputStream(sourceFile);
//			   FileOutputStream out = new FileOutputStream(destFile);
//
//			   byte[] cache = new byte[CACHE_SIZE];
//			   int nRead = 0;
//			   while ((nRead = in.read(cache)) != -1) {
//				   out.write(cache, 0, nRead);
//				   out.flush();
//			   }
//			   out.close();
//			   in.close();
//	}


	public static void downloadFileToPath(String sourceFilePath, String fileName, HttpServletResponse resp) throws Exception{
		String realName = fileName;
		try{
			realName =    URLEncoder.encode(realName,"utf-8");

		}catch (Exception e){

		}

		resp.setContentType("multipart/form-data");//通知浏览器数据类型
		resp.addHeader("Content-Disposition", "attachment;filename=" + realName);//告诉浏览器文件名
		ServletOutputStream out = null;

		try {
			File sourceFile = new File(sourceFilePath);
		   if (sourceFile.exists() && sourceFile.isFile()) {

			   FileInputStream in = new FileInputStream(sourceFile);
			   out = resp.getOutputStream();

			   byte[] cache = new byte[CACHE_SIZE];
			   int nRead = 0;
			   while ((nRead = in.read(cache)) != -1) {
				   out.write(cache, 0, nRead);
				   out.flush();
			   }
		   }
		} catch (IOException e) {
			e.printStackTrace();
		}
	}





//	public static void main(String args[]) throws Exception{
//		String key = "5662e7c3d61fd5e0e67acd8bace6d1b0";
//		String sourceFilePath = "C:\\Users\\reyun\\Desktop\\reyunCrypto.jar";
//		String destFilePath = "C:\\Users\\reyun\\Desktop\\new.jar";
//		encryptFile(key, sourceFilePath,destFilePath);
////		decryptFile(key, destFilePath, sourceFilePath);
//
////		InputStream in = new FileInputStream(sourceFilePath);
////		System.out.println(inputStreamToString(in));
////		downloadFileToPath(sourceFilePath, "C:\\Users\\reyun\\Desktop\\mongo.jar");
//    }

}
