package com.qy.utils;

import com.qy.Interfaces.SmaliApkToolsPath;
import org.json.JSONObject;

import java.io.*;
import java.util.Objects;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class AutoPackageSDKMust {
    private String key;
    private SmaliApkToolsPath path;
    private JSONObject config;
    private String sdkCode = " String RDCpplictPath=Decode.getData(\"RDCpplictPath\");";
    private boolean isAddRandomCode = false;

    private AutoPackageSDKMust(String key, SmaliApkToolsPath path) {
        this.key = key;
        this.path = path;
        config = Tools.loadConfig(new File("config.cfg"));
        start();
    }

    public static void start(String key, SmaliApkToolsPath path) {
        new AutoPackageSDKMust(key, path);
    }

    private void start() {
        if (true) {
            copySDK();
            File sdk_src = new File("sdk_src" + File.separator + "sdk" + File.separator + "src" + File.separator + "main" + File.separator + "java");
            loadFile(sdk_src);
            path.smaliPath(packageSDK());
        } else {
            System.out.println(encrypt(sdkCode));
            System.out.println(AESTools.aesDecrypt("655312476E8F4F12A72E1AB1C3CF8032", key));
        }
    }

    private void copySDK() {
        File sdkPath = new File(config.getString("sdkPath"));
        if (!sdkPath.exists()) {
            path.smaliPath(null);
            return;
        }
        File sdk_src = new File("sdk_src");
        sdk_src.mkdirs();
        Tools.copyFile(sdkPath.getAbsolutePath() + File.separator + "build.gradle", sdk_src.getAbsolutePath() + File.separator, true);
        Tools.copyFile(sdkPath.getAbsolutePath() + File.separator + "gradlew", sdk_src.getAbsolutePath() + File.separator, true);
        Tools.copyFile(sdkPath.getAbsolutePath() + File.separator + "gradlew.bat", sdk_src.getAbsolutePath() + File.separator, true);
        Tools.copyFile(sdkPath.getAbsolutePath() + File.separator + "settings.gradle", sdk_src.getAbsolutePath() + File.separator, true);
        Tools.copyFile(sdkPath.getAbsolutePath() + File.separator + "local.properties", sdk_src.getAbsolutePath() + File.separator, true);
        try {
            BufferedReader reader;
            Process process = Runtime.getRuntime().exec("xcopy " + sdkPath.getAbsolutePath() + File.separator + "gradle " + sdk_src.getAbsolutePath() + File.separator + "gradle /E /I /Y");
            reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            while (reader.readLine() != null) ;
            reader.close();
            process = Runtime.getRuntime().exec("xcopy " + sdkPath.getAbsolutePath() + File.separator + "sdk " + sdk_src.getAbsolutePath() + File.separator + "sdk /E /I /Y");
            reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            while (reader.readLine() != null) ;
            reader.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("复制完全");
    }

    private void loadFile(File path) {
        for (File file : Objects.requireNonNull(path.listFiles())) {
            if (file.isDirectory()) {
                loadFile(file);
            } else if (file.getName().endsWith(".java")) {
                if (!file.getName().equals("Decode.java")) {
                    loadCode(file);
                } else {
                    try {
                        BufferedReader reader = new BufferedReader(new FileReader(file));
                        StringBuilder builder = new StringBuilder();
                        String tmp = null;
                        while ((tmp = reader.readLine()) != null) {
                            if (tmp.contains("String key=")) {
                                tmp = tmp.replace("\"\"", "\"" + key + "\"");
                            }
                            builder.append(tmp).append("\n");
                        }
                        reader.close();
                        FileWriter writer = new FileWriter(file);
                        writer.write(builder.toString());
                        writer.flush();
                        writer.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                }
            }
        }
    }

    private void loadCode(File java) {
        try {
            BufferedReader reader = new BufferedReader(new FileReader(java));
            StringBuilder builder = new StringBuilder();
            String tmp = null;
            int braceCount = 0;
            boolean isMethod = false;
            boolean isUserDecode = false;
            String endWriter = "";
            String endImport = "";
            String oldCode = "";
            String packagePath = "";
            while ((tmp = reader.readLine()) != null) {
                tmp = encrypt(tmp);
                if (isAddRandomCode) {
                    if (tmp.startsWith("package")) {
                        packagePath = tmp;
                    }
                    oldCode = tmp;
                    if (tmp.contains("import com.qy.sdk.Utils.Decode;")) {
                        isUserDecode = true;
                    }
                    if (tmp.startsWith("import")) {
                        endImport = tmp;
                    }
                    if (tmp.replace(" ", "").contains("){")) {
                        isMethod = true;
                    }
                    if (tmp.contains("{")) {
                        braceCount++;
                    }
                    if (tmp.contains("}")) {
                        braceCount--;
                        if (braceCount == 0) {
                            isMethod = false;
                        }
                    }
                    if (isMethod) {
                        if (new Random().nextDouble() > 0.7d && (oldCode.contains(";") && !oldCode.contains("return")
                                && !oldCode.contains("=") && !oldCode.endsWith(")") && !oldCode.contains("continue")
                                && !oldCode.contains("break") && !oldCode.contains("public")
                                && !oldCode.contains("private") && !oldCode.contains("static"))) {
                            endWriter = "Decode.log(\"" + Tools.getRandomString(16) + "\");";
                            tmp += "\n" + endWriter;
                        }
                    }
                }
                builder.append(tmp).append("\n");
            }
            tmp = builder.toString();
            if (!isUserDecode&&isAddRandomCode) {
                if (endImport.trim().length() == 0) {
                    endImport = packagePath;
                }
                tmp = tmp.replace(endImport, endImport + "\nimport com.qy.sdk.Utils.Decode;\n");
            }
            tmp = tmp.replace(endWriter, "");
            reader.close();
            FileWriter writer = new FileWriter(java);
            writer.write(tmp);
            writer.flush();
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private String encrypt(String tmp) {
        Pattern pattern = Pattern.compile("\\\"([^\\\"]*)\\\"");
        Matcher matcher = pattern.matcher(tmp);
        while (matcher.find()) {
            String code = tmp.substring(matcher.start(), matcher.end());
            String encrypt = AESTools.aesEncrypt(code.replace("\"", ""), key);
            if (encrypt != null) {
                tmp = tmp.replace(code, "$#&" + encrypt + "$#&");
            }
            matcher = pattern.matcher(tmp);
        }
        tmp = tmp.replace("$#&", "\"");
        return tmp;
    }

    private String packageSDK() {
        File sdk_src = new File("sdk_src");
        try {
            Process process = Runtime.getRuntime().exec(sdk_src.getAbsolutePath() + File.separator + "gradlew.bat assembleRelease -p " + sdk_src.getAbsolutePath() + File.separator + "sdk");//打包sdk
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String tmp;
            while ((tmp = reader.readLine()) != null) {
                System.out.println(tmp);
            }
            process.waitFor();
            reader.close();
            return sdk_src.getAbsolutePath() + File.separator + "sdk" + File.separator + "build" + File.separator
                    + "intermediates" + File.separator + "aar_main_jar" + File.separator + "release" + File.separator + "classes.jar";
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        start("eZMpiVponpIUV5VO", new SmaliApkToolsPath() {
            @Override
            public void smaliPath(String path) {
                System.out.println("over=" + path);
            }
        });
    }
}
