package com.qy.utils;

import com.qy.Interfaces.SmaliApkToolsPath;
import com.qy.ui.EditToDalog;
import org.json.JSONArray;
import org.json.JSONObject;

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

public class CsjTools {
    private static String csj_res = "D:\\IdeaProjects\\android_sdk_tools\\demo_2.8.0.2\\res\\values";
    private static String apk_res = "D:\\IdeaProjects\\android_sdk_tools\\app-release\\res\\values";
    private static String apk_Path = "D:\\IdeaProjects\\android_sdk_tools\\app-release";
    private static String csj_Path = "D:\\IdeaProjects\\android_sdk_tools\\demo_2.8.0.2";
    private List<String> r_list;

    public CsjTools() {
    }

    public String loadXml(String path) {
        File file = new File(path);
        String xml = null;
        try {
            BufferedReader reader = new BufferedReader(new FileReader(file));
            String tmp;
            while ((tmp = reader.readLine()) != null) {
                if (xml == null) {
                    xml = tmp + "\n";
                } else {
                    xml += tmp + "\n";
                }
            }
            reader.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return xml;
    }


    public long getId(String publicXml) {
        long maxId = 0;
        for (String xml : publicXml.split("\n")) {
            String id = getXMLValue("id", xml.trim());
            if (id != null) {
                id = id.substring(2, 6);
                if (maxId < Long.parseLong(id, 16)) {
                    maxId = Long.parseLong(id, 16);
                }
            }

        }
        return maxId;

    }

    public String getXMLValue(String name, String message) {
        Pattern p = Pattern.compile(name + "=\"([^\"]+)\"");
        Matcher m = p.matcher(message);
        if (m.find()) {
            String tmp = message.substring(m.start(), m.end()).split("=")[1];
            return tmp.substring(1, tmp.length() - 1);
        }
        return null;
    }
    private boolean isAppPackageName =false;
    public void setUserPackageName(boolean isAppPackageName){
        this.isAppPackageName=isAppPackageName;
    }
    private String getPackageName() {
        try {
            if(isAppPackageName) {
                File apkManifest = new File(apk_Path + File.separator + "AndroidManifest.xml");
                BufferedReader reader = new BufferedReader(new FileReader(apkManifest));
                String tmp = reader.readLine();
                reader.close();
                return getXMLValue("package", tmp);
            }else{
                return "com.prujwk.jdyphn";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private void outManifest() {
        try {
            File apkManifest = new File(apk_Path + File.separator + "AndroidManifest.xml");
            File demoManifest = new File(csj_Path + File.separator + "AndroidManifest.xml");
            BufferedReader reader = new BufferedReader(new FileReader(apkManifest));
            String tmp = reader.readLine();
            reader.close();
            String apkPackage = getXMLValue("package", tmp);
            System.out.println(apkPackage);
            _log.smaliPath("获取到APK包名：" + apkPackage);
            reader = new BufferedReader(new FileReader(demoManifest));
            tmp = reader.readLine();
            String manifest = tmp.replace(getXMLValue("package", tmp), apkPackage) + "\n";
            while ((tmp = reader.readLine()) != null) {
                manifest += tmp + "\n";
            }
            FileWriter writer = new FileWriter(demoManifest);
            writer.write(manifest);
            writer.flush();
            writer.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void out(String srcFile, String encryptFile, int version) {
        EncryptJar encryptJar = new EncryptJar();
        encryptJar.encrypt(new File(srcFile), encryptFile, 13, version);

    }


    private void commandFile() {
        JSONObject config = Tools.loadConfig(new File("config.cfg"));
        if (config != null && config.getJSONObject("csjConfig") != null) {
            JSONObject _config = config.getJSONObject("csjConfig");
            JSONObject fileConfig = _config.getJSONObject("file");
            JSONArray data = fileConfig.getJSONArray("data");
            for (Object _item : data) {
                JSONObject item = (JSONObject) _item;
                String path = item.getString("name");
                if (item.getString("command").equals("delete")) {
                    path = path.replace("${demoRoot}", csj_Path)
                            .replace("${apkRoot}", apk_Path)
                            .replace("/", File.separator);
                    File file = new File(path.replace("*", ""));
                    if (path.endsWith("*")) {
                        Tools.deleteFiles(file.getAbsolutePath());
                    } else {
                        file.delete();
                    }
                }
            }
            _config = config.getJSONObject("csjConfig").getJSONObject("xml");
            if (_config != null) {
                data = _config.getJSONArray("data");
                for (Object _item : data) {
                    JSONObject item = (JSONObject) _item;
                    if (item.getString("command").equals("remove")) {
                        String path = item.getString("name")
                                .replace("${demoRoot}", csj_Path)
                                .replace("${apkRoot}", apk_Path)
                                .replace("/", File.separator);
                        File file = new File(path);
                        commandXml(file, item);
                    }
                }
            }
        }
    }

    private void commandXml(File file, JSONObject item) {
        try {
            String fileXml = loadXml(file.getAbsolutePath());
            String newXml = "";
            boolean remove = false;
            for (String xml : fileXml.split("\n")) {
                for (Object data : item.getJSONArray("data")) {
                    JSONObject _item = (JSONObject) data;
                    String value = getXMLValue(_item.getString("title"), xml.trim());
                    if (value != null && value.equals(_item.getString("value"))) {
                        remove = true;
                    }
                }
                if (remove) {
                    remove = false;
                    continue;
                }
                newXml += xml + "\n";

            }
            FileWriter writer = new FileWriter(file);
            writer.write(newXml);
            writer.flush();
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void start() {
        _log.smaliPath("开始制作资源包");

        commandFile();
        String apkXML = loadXml(apk_res + File.separator + "public.xml");
        String demoXML = loadXml(csj_res + File.separator + "public.xml");
        long maxId = getId(apkXML);
        int index = 0;
        String message = "";
        String oldType = "";
        for (String xml : demoXML.split("\n")) {
            String type = getXMLValue("type", xml.trim());
            //   String name = getXMLValue("name", xml.trim());
            String oldId = getXMLValue("id", xml.trim());
            if (type != null && !type.equals(oldType)) {
                oldType = type;
                maxId++;
                index = 0;
            }
            if (type != null) {
                String nextId = "0x" + Long.toHexString(maxId + 1) + String.format("%.3f", (index++) / 1000f).replace(".", "");
                xml = xml.replace(oldId, nextId);
            }
            message += xml + "\n";
        }
        try {
            FileWriter writer = new FileWriter(new File(csj_res + File.separator + "public.xml"));
            writer.write(message);
            writer.flush();
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        outManifest();
        File csjRes = new File("csj" + File.separator + "csc.apk");
        if (!new File("csj").exists()) {
            new File("csj").mkdirs();
        }
        SmaliUtils utils = new SmaliUtils();
        _log.smaliPath("资源包制作完成，开始打包为apk");
        utils.bale(csj_Path, csjRes.getAbsolutePath(), new SmaliApkToolsPath() {
            @Override
            public void smaliPath(String path) {
                _log.smaliPath("已出包" + csjRes.getAbsolutePath());
                _log.smaliPath("耗时:" + (System.currentTimeMillis() - time) / 1000 + " 秒");

            }
        });
    }

    private long time;
    private boolean unPackageCSJ = false;
    private SmaliApkToolsPath _log;

    public void build(String csjPath, String apkPath, SmaliApkToolsPath log) {
        time = System.currentTimeMillis();
        _log = log;
        unPackageCSJ = false;
        File csjFile = new File(csjPath);
        //由于改成动态SDK，所以每个应用都要单独打包
        /*if (new File(csjFile.getName().replace(".apk", "")).exists()) {
            System.out.println(">?>>" + new File(csjFile.getName().replace(".apk", "")).getAbsolutePath());
            unPackageCSJ = true;
            csj_Path = new File(csjFile.getName().replace(".apk", "")).getAbsolutePath();
            csj_res = csj_Path + File.separator + "res" + File.separator + "values";
        }*/
        SmaliUtils utils = new SmaliUtils();
        Tools.deleteFiles(new File("").getAbsolutePath() + File.separator + new File(csjPath).getName().replace(".apk", File.separator));
        Tools.deleteFiles(new File("").getAbsolutePath() + File.separator + new File(apkPath).getName().replace(".apk", File.separator));


        new Thread(new Runnable() {
            @Override
            public void run() {
                _log.smaliPath("开始反编译目标APK");


                utils.unPack(apkPath, new SmaliApkToolsPath() {
                    @Override
                    public void smaliPath(String path) {
                        log.smaliPath("目标APK反编译完成:" + path);
                        apkUnPackage = true;
                        System.out.println(path);
                        apk_Path = path;
                        apk_res = apk_Path + File.separator + "res" + File.separator + "values";
                        runStart();
                    }
                });

                if (unPackageCSJ) {
                    _log.smaliPath("穿山甲demo已存在，不再反编译");
                    csjManifest = true;
                    runStart();
                } else {
                    _log.smaliPath("开始反编译穿山甲Demo");
                    utils.unPack(csjPath, new SmaliApkToolsPath() {
                        @Override
                        public void smaliPath(String path) {
                            _log.smaliPath("穿山甲Demo反编译完成:" + path);
                            System.out.println(path);
                            csj_Path = path;
                            csj_res = csj_Path + File.separator + "res" + File.separator + "values";
                            _log.smaliPath("开始修改穿山甲");
                            new Thread(new Runnable() {
                                @Override
                                public void run() {
                                    new AutoRandomAdSDK().startNotUnPackage(path, getPackageName(), new SmaliApkToolsPath() {
                                        @Override
                                        public void smaliPath(String path) {
                                            _log.smaliPath("穿山甲修改完成");
                                            System.out.println("-------" + path);
                                            csjManifest = true;
                                            runStart();
                                        }
                                    });
                                }
                            }).start();
                        }

                    });
                }
            }
        }).start();

    }

    boolean csjManifest = false;
    boolean apkUnPackage = false;

    private void runStart() {
        if (apkUnPackage && csjManifest) {
            start();
        }
    }

    //还有最后一个问题，穿山甲的Activity没改
    public static void main(String[] args) {
        CsjTools tools = new CsjTools();
        tools.build("D:\\IdeaProjects\\android_sdk_tools\\demo_2.8.0.2.apk",
                "D:\\IdeaProjects\\android_sdk_tools\\app-release.apk",
                new SmaliApkToolsPath() {
                    @Override
                    public void smaliPath(String log) {
                        System.out.println(log);
                        if (log.startsWith("已出包")) {
                            System.out.println("打包完成");
                            new EditToDalog("成功", "打包完成，请输入版本号", "5600", new SmaliApkToolsPath() {
                                @Override
                                public void smaliPath(String path) {
                                    System.out.println(">>" + path);
                                    tools.out(log.replace("已出包", ""),
                                            new File("csj").getAbsolutePath() + File.separator + "csc",
                                            Integer.parseInt(path));
                                }
                            });
                        }
                    }
                });

        // tools.outManifest();
        // tools.start();

    }
}
