package com.qy.utils;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Random;
import java.util.jar.JarOutputStream;
import java.util.zip.CRC32;
import java.util.zip.CheckedInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import org.json.JSONObject;

import static java.util.zip.ZipEntry.STORED;


public class Tools {
	public static boolean stringIsNull(String string) {
		if (string == null || string.length() == 0) {
			return true;
		}
		return false;
	}

	public static String getRandomString(int length) {
		String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
		Random random = new Random();
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < length; i++) {
			int number = random.nextInt(str.length());
			sb.append(str.charAt(number));
		}
		return sb.toString();
	}
	public static int getRandomInt(int min,int max) {
		int i=new Random().nextInt(max);
		if(i<min) {
			return getRandomInt(min, max);
		}
		return i;
	}
	public static void deleteFiles(String path) {
		File files = new File(path);
		if (files.exists()) {
			if (files.isDirectory()) {
				for (File file : files.listFiles()) {
					deleteFiles(file.getAbsolutePath());
				}
			}
			//   System.out.println("删除文件 "+files.getAbsolutePath());
			files.delete();
		}
	}
	public static boolean copyFileToName(String srcFileName,String destFileName,String fileName,boolean overlay) {
		File srcFile = new File(srcFileName);
		// 判断源文件是否存在
		if (!srcFile.exists()) {
			System.err.println("源文件不存在："+srcFile.getAbsolutePath());
			return false;
		} else if (!srcFile.isFile()) {
			System.err.println("源文件是目录:"+srcFile.getAbsolutePath());
			return false;
		}

		// 判断目标文件是否存在
		File destFile = new File(destFileName);
		// 如果目标文件所在目录不存在，则创建目录
		if (!destFile.exists()) {
			// 目标文件所在目录不存在
			if (!destFile.mkdirs()) {
				// 复制文件失败：创建目标文件所在目录失败
				System.err.println("创建文件夹失败");
				return false;
			}

		}else{
			if(srcFileName.equals("Activity.smali")){
				System.out.println("文件夹已存在："+destFileName);
			}
		}

		// 复制文件
		int byteread = 0; // 读取的字节数
		InputStream in = null;
		OutputStream out = null;

		try {
			if(fileName==null) {
				fileName=srcFile.getName();
			}
			in = new FileInputStream(srcFile);
			out = new FileOutputStream(destFile + File.separator +fileName );
			byte[] buffer = new byte[1024];

			while ((byteread = in.read(buffer)) != -1) {
				out.write(buffer, 0, byteread);
			}
			out.close();
			in.close();
			return true;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return false;
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
	}
	/**
	 * 复制单个文件
	 *
	 * @param srcFileName  待复制的文件名
	 * @param destFileName 目标文件名
	 * @param overlay      如果目标文件存在，是否覆盖
	 * @return 如果复制成功返回true，否则返回false
	 */
	public static boolean copyFile(String srcFileName, String destFileName,
								   boolean overlay) {
		if(new File(srcFileName).isDirectory()){
			return copyDir(srcFileName,destFileName);
		}else {
			return copyFileToName(srcFileName, destFileName, null, overlay);
		}
	}
	private static boolean copyDir(String dir,String dest){
		try{
			//System.out.println("复制文件"+dir+"到"+dest);
			File src=new File(dir);
			File destFile=new File(dest);
			String path="";
			int index;
			String ta,tb;
			if(dir.length()>dest.length()){
				index=dir.length();
				ta=dir;
				tb=dest;
			}else{
				index=dest.length();
				ta=dest;
				tb=dir;
			}
			for (int i = 0; i < index; i++) {
				if(tb.length()>(i+1)&&ta.substring(i,i+1).equals(tb.substring(i,i+1))){
					path+=ta.substring(i,i+1);
				}else {
					break;
				}
			}
			if(!destFile.exists()){
				destFile.mkdirs();
			}
			for (File file : src.listFiles()) {
				if(file.isDirectory()){
					copyDir(file.getAbsolutePath(),dest);
				}else{
					String tmp=file.getAbsolutePath().replace(file.getName(),"").replace(new File("input"+File.separator+"Documents"+File.separator+"copy"+File.separator).getAbsolutePath(),"");
					System.out.println(file.getAbsolutePath()+"  "+tmp);
					File out=new File(dest+tmp);
					if(!out.exists()){
						out.mkdirs();
					}
					copyFile(file.getAbsolutePath(),out.getAbsolutePath(),true);
				}
			}
		}catch (Exception e){
			e.printStackTrace();
			return false;
		}
		return true;
	}

	public static JSONObject loadConfig(File file) {
		JSONObject json = null;
		BufferedReader reader;
		if (!file.exists()) {
			try {
				file.createNewFile();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} else {
			String tmp, str = "";
			try {
				reader = new BufferedReader( new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8));
				while ((tmp = reader.readLine()) != null) {
					str += tmp;
				}
				json = new JSONObject(str);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				System.out.println(str);
			}
		}
		return json;
	}

	public static void toZip(String srcDir, File file, boolean KeepDirStructure,boolean zipRootName) throws RuntimeException {

		long start = System.currentTimeMillis();
		ZipOutputStream zos = null;
		try {
			zos = new ZipOutputStream(new FileOutputStream(file));
			File sourceFile = new File(srcDir);
			compress(sourceFile, zos,file.getName(), sourceFile.getName(), KeepDirStructure,zipRootName);
			long end = System.currentTimeMillis();
			System.out.println("压缩完成，耗时：" + (end - start) + " ms");
		} catch (Exception e) {
			throw new RuntimeException("zip error from ZipUtils", e);
		} finally {
			if (zos != null) {
				try {
					zos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

	}
	private static void compress(File sourceFile, ZipOutputStream zos,String zipName, String name, boolean KeepDirStructure,boolean zipRootName)
			throws Exception {
		byte[] buf = new byte[ 2 * 1024];

		if (sourceFile.isFile()) {
			if(sourceFile.getName().equals(zipName)){
				return;
			}
			// 向zip输出流中添加一个zip实体，构造器中name为zip实体的文件的名字
			ZipEntry entry=new ZipEntry(name);
			/*entry.setMethod(STORED);
			entry.setSize(sourceFile.length());
			long crc=0;
			crc=calFileCRC32(sourceFile);
			entry.setCrc(crc);*/
			zos.putNextEntry(entry);
			// copy文件到zip输出流中
			int len;
			FileInputStream in = new FileInputStream(sourceFile);
			while ((len = in.read(buf)) != -1) {
				zos.write(buf, 0, len);
			}
			// Complete the entry
			zos.closeEntry();
			in.close();
		} else {
			File[] listFiles = sourceFile.listFiles();
			if (listFiles == null || listFiles.length == 0) {
				// 需要保留原来的文件结构时,需要对空文件夹进行处理
				if (KeepDirStructure) {
					// 空文件夹的处理
					ZipEntry entry=new ZipEntry(name + File.separator);
					zos.putNextEntry(entry);
					// 没有文件，不需要文件的copy
					zos.closeEntry();
				}

			} else {
				for (File file : listFiles) {
					// 判断是否需要保留原来的文件结构
					if (KeepDirStructure) {
						// 注意：file.getName()前面需要带上父文件夹的名字加一斜杠,
						// 不然最后压缩包中就不能保留原来的文件结构,即：所有文件都跑到压缩包根目录下了
						if(zipRootName) {
							compress(file, zos, zipName,name + File.separator + file.getName(),  KeepDirStructure,zipRootName);
						}else{
							if(name.startsWith("\\")){
								compress(file, zos, zipName,name + File.separator + file.getName(),  KeepDirStructure,zipRootName);
							}else {
								compress(file, zos,zipName, File.separator + file.getName(), KeepDirStructure, zipRootName);
							}
						}
					} else {
						compress(file, zos, zipName,file.getName(), KeepDirStructure,zipRootName);
					}

				}
			}
		}
	}
	public static long calFileCRC32(File file) throws IOException {
		FileInputStream fi = new FileInputStream(file);
		CheckedInputStream checksum = new CheckedInputStream(fi, new CRC32());
		while (checksum.read() != -1) { }
		long temp = checksum.getChecksum().getValue();
		fi.close();
		checksum.close();
		return temp;
	}
	public static void toAJar(String dx,String inName,String outName) {

		try {
			File file=new File(outName);
			if(file.exists()) {
				file.delete();
			}
			String exec="java -jar "+dx+"  --dex --output="+outName+" "+inName+"";
			System.out.println("java to dex:"+exec);
			Process process=Runtime.getRuntime().exec(exec);
			process.waitFor();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
