package com.qy.sms;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

import com.qy.utils.Tools;
import com.qy.utils.WorldTools;

import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.util.Zip4jConstants;

public class SDKTools {
	public static String a, b, c;
	public static String packName;
	public static String srcPackName = "com.jobs.sdk";
	public static String sdkDatapath;
	public static String GameSDKManageName = "GameSDKManage";
	public static Map<String, String> sdkfunction;
	private static String dataFolder = "data";
	public static String version = "2.24";

	public static void start(String descDir) {
		SDKTools tools = new SDKTools();
		tools.initName();
		tools.unSDKzip(descDir);
		tools.resdk();
		tools.reCode(SDKTools.sdkDatapath);
		tools.reGameSDKManage();
		tools.classPath.add(new File(dataFolder).getAbsolutePath() + "\\android.jar");
		tools.classPath.add(new File(dataFolder).getAbsolutePath() + "\\androidv4.jar");
		tools.saveJavaPath(sdkDatapath);
		tools.javaToClass(sdkDatapath);
		System.out.println("清理文件:" + sdkDatapath);
		tools.deleteJava(sdkDatapath);
		tools.toJarforJar();
		WorldTools.start(packName, GameSDKManageName, sdkfunction);

	}

	private void initName() {
		sdkfunction = new HashMap<>();
		sdkfunction.put("getSDKManage", "get" + Tools.getRandomString(Tools.getRandomInt(5, 12)));
		sdkfunction.put("init", Tools.getRandomString(Tools.getRandomInt(5, 12)));
		sdkfunction.put("regMethod", Tools.getRandomString(Tools.getRandomInt(5, 12)));
		sdkfunction.put("stop", Tools.getRandomString(Tools.getRandomInt(5, 12)));
		sdkfunction.put("pay", Tools.getRandomString(Tools.getRandomInt(5, 12)));
		sdkfunction.put("authority", Tools.getRandomString(Tools.getRandomInt(5, 12)));
		sdkfunction.put("getTextAlpha", Tools.getRandomString(Tools.getRandomInt(5, 12)));
		sdkfunction.put("setLog", Tools.getRandomString(Tools.getRandomInt(5, 12)));
		sdkfunction.put("getVersion", Tools.getRandomString(Tools.getRandomInt(5, 12)));
		sdkfunction.put("getPermission", Tools.getRandomString(Tools.getRandomInt(5, 12)));
	}

	public void unSDKzip_(String descDir) {
		try {
			File sdkPath = new File(new File("").getAbsolutePath() + "/smsdk/");
			System.out.println(sdkPath + "  " + sdkPath.exists());
			if (sdkPath.exists()) {
				Tools.deleteFiles(sdkPath.getAbsolutePath());
			}
			File zipFile = new File(new File(dataFolder).getAbsolutePath() + "/sdk.zip");
			System.out.println("解压sdk源码:"+zipFile.getAbsolutePath());
			ZipFile zip = new ZipFile(zipFile);
			for (Enumeration<?> entries = zip.entries(); entries.hasMoreElements();) {
				ZipEntry entry = (ZipEntry) entries.nextElement();
				String zipEntryName = entry.getName();
				InputStream in = zip.getInputStream(entry);
				String outPath = (descDir + "/" + zipEntryName).replace("\\", "/");
				// 判断路径是否存在,不存在则创建文件路径
				File file = new File(outPath.substring(0, outPath.lastIndexOf('/')));
				if (!file.exists()) {
					file.mkdirs();
				}
				// 判断文件全路径是否为文件夹,如果是上面已经上传,不需要解压
				if (new File(outPath).isDirectory()) {
					continue;
				}
				// 输出文件路径信息
				System.out.println(outPath);
				OutputStream out = new FileOutputStream(outPath);
				byte[] buf1 = new byte[1024];
				int len;
				while ((len = in.read(buf1)) > 0) {
					out.write(buf1, 0, len);
				}
				in.close();
				out.close();
			}
			zip.close();
			System.out.println("******************解压完毕********************");
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}
	private void unSDKzip(String descDir) {
		try {
			File sdkPath = new File(new File("").getAbsolutePath() + "/smsdk/");
			System.out.println(sdkPath + "  " + sdkPath.exists());
			if (sdkPath.exists()) {
				Tools.deleteFiles(sdkPath.getAbsolutePath());
			}
			File zipFile = new File(new File(dataFolder).getAbsolutePath() + "/sdk.zip");
			System.out.println("解压sdk源码:"+zipFile.getAbsolutePath());
			net.lingala.zip4j.core.ZipFile zip=new net.lingala.zip4j.core.ZipFile(zipFile);
			zip.setFileNameCharset("GBK");
			zip.extractAll(new File("").getAbsolutePath());
			System.out.println("******************解压完毕********************");
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}

	public void resdk() {
		File sdkPath = new File(new File("").getAbsolutePath() + "/smsdk/");
		if (!sdkPath.exists()) {
			System.out.println("SDK目录不存在 " + sdkPath.getAbsolutePath());
			return;
		}
		a = Tools.getRandomString(3);
		b = Tools.getRandomString(4);
		c = Tools.getRandomString(4);
		packName = a + "." + b + "." + c;
		System.out.println("SDK包名：" + packName);
		rename(sdkPath);
	}

	private void rename(File folder) {
		String tmp = "", tmp2 = "";
		if (folder.exists() && folder.isDirectory()) {
			switch (folder.getName()) {
			case "com":
				tmp = "com";
				folder.renameTo(new File(new File("smsdk").getAbsolutePath() + File.separator + a));
				tmp2 = a;
				break;
			case "jobs":
				tmp = "jobs";
				folder.renameTo(new File(new File("smsdk/" + a).getAbsolutePath() + File.separator + b));
				tmp2 = b;
				break;
			case "sdk":
				tmp = "sdk";
				tmp2 = c;
				sdkDatapath = new File("smsdk/" + a + "/" + b).getAbsolutePath() + File.separator + c;
				folder.renameTo(new File(sdkDatapath));
				break;
			default:
				break;
			}
			System.out.println(sdkDatapath + "  " + folder.getAbsolutePath() + " " + tmp + " " + tmp2);
			folder = new File(folder.getAbsolutePath().replace(File.separator + tmp, File.separator + tmp2));
			System.out.println(folder.getAbsolutePath());
			for (File fold : folder.listFiles()) {
				if (fold.isDirectory()) {
					rename(fold);
				}
			}
		}
	}

	public void reCode(String path) {
		File file = new File(path);
		for (File f : file.listFiles()) {
			if (f.isDirectory()) {
				reCode(f.getAbsolutePath());
			} else if (f.getName().contains(".java")) {
				reJava(f);
			}
		}
	}

	private void reJava(File java) {
		try {
			BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(java), "UTF-8"));
			String str = "", tmp;
			while ((tmp = reader.readLine()) != null) {
				if (tmp.contains(srcPackName)) {
					tmp = tmp.contains(srcPackName + "_rx") ? tmp : tmp.replace(srcPackName, packName);
				}
				str += tmp + "\n";
			}
			reader.close();
			PrintWriter writer = new PrintWriter(java);
			writer.write(str);
			writer.flush();
			writer.close();
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}

	private void reGameSDKManage() {
		File java = new File(sdkDatapath + "/GameSDKManage.java");
		if (!java.exists()) {
			System.out.println("GameSDKManage.java不存在");
			return;
		}
		GameSDKManageName = Tools.getRandomString(Tools.getRandomInt(4, 8));
		File javaName = new File(java.getAbsolutePath().replace(java.getName(), GameSDKManageName + ".java"));
		try {
			BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(java)));
			String str = "", tmp;
			while ((tmp = reader.readLine()) != null) {
				tmp = tmp.replace("GameSDKManage", GameSDKManageName);
				tmp = tmp.replace("getSDKManage", sdkfunction.get("getSDKManage"));
				tmp = tmp.replace("init", sdkfunction.get("init"));
				tmp = tmp.replace("regMethod", sdkfunction.get("regMethod"));
				tmp = tmp.replace("stop", sdkfunction.get("stop"));
				tmp = tmp.replace("pay", sdkfunction.get("pay"));
				tmp = tmp.replace("authority", sdkfunction.get("authority"));
				tmp = tmp.replace("getTextAlpha", sdkfunction.get("getTextAlpha"));
				tmp = tmp.replace("setLog", sdkfunction.get("setLog"));
				tmp = tmp.replace("getVersion", sdkfunction.get("getVersion"));
				tmp = tmp.replace("getPermission", sdkfunction.get("getPermission"));
				str += tmp + "\n";
			}
			reader.close();
			PrintWriter writer = new PrintWriter(javaName);
			writer.write(str);
			writer.flush();
			writer.close();
			java.delete();
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}

	private List<String> classPath = new ArrayList<>();
	private List<String> javaPath = new ArrayList<>();

	private void saveJavaPath(String path) {
		File file = new File(path);
		for (File f : file.listFiles()) {
			if (f.isDirectory()) {
				saveJavaPath(f.getAbsolutePath());
			} else if (f.getName().contains(".java")) {
				javaPath.add(f.getAbsolutePath());
			}
		}
	}

	private void javaToClass(String path) {
		File file = new File(path);
		for (File f : file.listFiles()) {
			if (f.isDirectory()) {
				javaToClass(f.getAbsolutePath());
			} else if (f.getName().contains(".java")) {
				try {
					String exec = "javac -classpath " + getClassPath() + "; -sourcepath " + getSourcePath() + " "
							+ f.getAbsolutePath() + "\n";
					System.out.println(exec);
					Process process = Runtime.getRuntime().exec(exec);
					process.waitFor();
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

	private void deleteJava(String path) {
		File file = new File(path);
		for (File f : file.listFiles()) {
			System.out.println("---->" + f.getAbsolutePath());
			if (f.isDirectory()) {
				deleteJava(f.getAbsolutePath());
			}
			if (f.getName().contains(".java")) {
				File ft = new File(f.getAbsolutePath().replace(".java", ".class"));
				if (ft.exists()) {
					f.delete();
					// System.out.println("删除java："+f.getAbsolutePath()+" "+t);
				}
			}
		}
	}

	private String getSourcePath() {
		String classpath = new File("smsdk").getAbsolutePath() + ";.";
		System.out.println("classpath: " + classpath);
		return classpath;
	}

	private String getClassPath() {
		String classPath = "";
		for (String str : this.classPath) {
			classPath += str + ";";
		}

		return classPath.substring(0, classPath.length() - 1);
	}


	public static void buildSDK(File sdkzip) {
		try {
			List<File> files = new ArrayList<>();
			List<ZipEntry> zips = new ArrayList<>();
			Map<String, File> fileNames = new HashMap<>();
			if (sdkzip == null)
				sdkzip = new File("计费sdk" + version + ".zip");
			if (sdkzip.exists())
				sdkzip.delete();
			ZipOutputStream output = new ZipOutputStream(new FileOutputStream(sdkzip));
			output.setLevel(Deflater.DEFLATED);

			File sdk = new File("sdk.jar");
			File word = new File("文档.txt");
			File rx = new File("data/rx.lt");
			File v4 = new File("data/androidv4.jar");
			File manifest = new File("data/manifest清单.txt");
			File permission = new File("data/权限列表.txt");

			files.add(sdk);
			files.add(word);
			files.add(rx);
			files.add(manifest);
			files.add(permission);
			files.add(v4);

			for (File file : files) {
				ZipEntry zip = new ZipEntry(file.getName());
				zips.add(zip);
				fileNames.put(zip.getName(), file);
			}

			for (ZipEntry zipEntry : zips) {
				output.putNextEntry(zipEntry);
				BufferedInputStream bis = new BufferedInputStream(
						new FileInputStream(fileNames.get(zipEntry.getName())));
				byte[] buffer = new byte[1024];
				int count;
				while ((count = bis.read(buffer)) != -1) {
					output.write(buffer, 0, count);
				}
				output.flush();
				bis.close();
			}
			output.closeEntry();
			output.close();

			 sdk.delete();
			word.delete();
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}
	private void toJarforJar() {
		try {
			Process process=Runtime.getRuntime().exec("jar cvf sdk.jar -C smsdk/ .");
			process.waitFor();
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}
	@Deprecated
	private void toJar() {
		try {
			File dir = new File("smsdk"+File.separator+a);
			ZipParameters par = new ZipParameters();
			par.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
			par.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
			net.lingala.zip4j.core.ZipFile zipFile=new net.lingala.zip4j.core.ZipFile(new File("sdk.zip"));
			jar(zipFile,dir, par);
			File zip=new File("sdk.zip");
			zip.renameTo(new File("sdk.jar"));
			zip.delete();
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}

	private void jar(net.lingala.zip4j.core.ZipFile zipFile, File file,ZipParameters par) throws Exception {
		toJar();
		for (File f : file.listFiles()) {
			System.out.println("压缩文件："+f.getAbsolutePath());
			if(f.isDirectory()) {
				par.setCompressionMethod(Zip4jConstants.COMP_STORE);
				File t=new File(f.getName());
				t.mkdirs();
				zipFile.addFolder(t, par);
				jar(zipFile, f, par);
			}else {
				par.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
				par.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
				zipFile.addFile(f, par);
			}
		}
		/*if(file.isDirectory()) {
			zipFile.addFolder(file, par);
		}else {
			zipFile.addFile(file, par);
		}*/
	}
}
