# -*-coding:utf-8-*-
import glob, os
import string
import random

class ActivityGarble:
    target = [
        "Activity.java",
        "Bean.java",
        "Fragment.java",
        "Receiver.java",
        "CertifyActiviy.java",
        "BaseApplication.java",
        "ContactEntity.java",
        "SmsEntity.java",
        "ActivityCenter.java",
        "Service.java",
        "Collector.java",
        "BannerMessageDto.java",
        "BasicAck.java",
        "InviteResult.java",
        "LoanAppBeanFatherStatusLogs.java",
        "LoanRange.java",
        "PhotoInfo.java",
        "IncomeMessageProto.java",
        "ResponseErrorBody.java",
        "RecordFilesResponse.java",
        "TotalAmount.java",
        "UserBankInfo.java",
        "YWUser.java"
        ]

    used_names = []
    activity_mapping = {}

    #随机串
    def __gen_rand_str(self):
        rand_str = ''.join(random.choices(string.ascii_uppercase + string.ascii_lowercase, k=8))
        while rand_str in self.used_names:
            rand_str = ''.join(random.choices(string.ascii_uppercase + string.ascii_lowercase, k=8))

        self.used_names.append(rand_str)
        return rand_str


    #替换文件内容
    def __process_file_content(self, path, file_name):
        # print("processing content: %s..."%path)
        with open(path, "rt") as fin:
            file_content = fin.read()
            # replace the file content based on mangle settings
            for (src, dst) in self.activity_mapping.items():
                separator = [" ", ".", "\"", "{", "}", "(", ")", "[", "]","<",">", ":",  ";", ","]
                for sep in separator:
                    file_content = file_content.replace(src + sep, dst + sep)

            ext = os.path.splitext(file_name)[1]
            if ext == '.java':
                comment = "// machine renamed: %s\n" % file_name
                file_content = "%s%s" % (comment, file_content)
            with open(path, "wt") as fout:
                fout.write(file_content)
        return

    #查找所有待混淆类 并重命名
    def __find_activities(self,path):
        for root, dirs, files in os.walk(path):
            directory = os.path.join(os.getcwd(), root)
            for file in files:
                is_activity = False
                for file_name in self.target:
                    if file.endswith(file_name):
                        is_activity = True

                if is_activity:
                    name = os.path.splitext(file)[0]
                    if name not in self.activity_mapping.keys():
                        self.activity_mapping[name] = self.__gen_rand_str()
                        src = os.path.join(directory, file)
                        dst = os.path.join(directory, "%s.java" % self.activity_mapping[name])
                        os.rename(src, dst)

    #遍历混淆文件
    def __process_files(self,path):
        for root, dirs, files in os.walk(path):
            directory = os.path.join(os.getcwd(), root)
            for file in files:
                if file.endswith(".java"):
                    self.__process_file_content(os.path.join(directory, file),file)


    #四大组件混淆
    def activity_garble(self,config):
        #找到要混淆的java文件
        print("find activity...")
        self.__find_activities("%s/app/src/main"% config['root'])
        self.__find_activities("%s/lib_base/src/main"% config['root'])
        
        #开始混淆
        print("start garble .java...")
        self.__process_files("%s/app/src/main"% config['root'])
        self.__process_files("%s/lib_base/src/main"% config['root'])

        #混淆AndroidManifest.xml
        print("start garble 混淆AndroidManifest.xml ...")
        manifest_path = os.path.join("%s/app/src/main/"% config['root'], "AndroidManifest.xml")
        self.__process_file_content(manifest_path,"AndroidManifest.xml")
        
        lib_manifest_path = os.path.join("%s/lib_base/src/main/"% config['root'], "AndroidManifest.xml")
        self.__process_file_content(lib_manifest_path,"AndroidManifest.xml")

        print("done")


if __name__ == "__main__":
    #project 根目录
    config = {"root" : "../../../../"}
    ActivityGarble().activity_garble(config)