import os
import time
import hashlib

apps_to_check_dir = "/home/ardalan/validation_set_from_fdroid_src_codes/compiled_from_src_codes"

def get_all_smali_in_folder(dir):
    res = []
    for root, dirs, files in os.walk(dir):
        for file in files:
            if file.endswith(".smali"):
                res.append(os.path.join(root, file))
    return res

app_counter = 0
for app in os.listdir(apps_to_check_dir):
    app_path = os.path.join(apps_to_check_dir, app)
    all_smali_files = get_all_smali_in_folder(app_path)
    for s in all_smali_files:
        a = str(os.path.relpath(s, apps_to_check_dir))
        a=a[a.find("/")+1:]
        a=a[a.find("/")+1:]
        a=a[a.find("/")+1:]
        if a.startswith("android/support"):
            continue
        if a.startswith("kotlin/"):
            continue
        if a.startswith("com/google/android"):
            continue
        if a.startswith("kotlinx/"):
            continue
        if a.startswith("androidx/"):
            continue
        lines = []
        with open(s, "r") as f:
            for l in f:
                l = l.strip()
                if l:
                    lines.append(l)

        methods_code_map = {}
        in_method = False
        method_name = None
        tmp = []
        in_annotation = False
        for l in lines:
            if l.startswith(".method") and "<init>" in l:
                in_method = True
                method_name = l.split(" ")[-1]
            elif l.startswith(".end method") and in_method:
                methods_code_map[method_name] = tmp
                tmp=[]
                method_name = None
                in_method = False
            elif in_method:
                if l.startswith(".line") or \
                        l.startswith(".prologue") or\
                        l.startswith(".param") or\
                        l.startswith(".local ") or\
                        l.startswith(".end param"):
                    continue
                elif l.startswith(".annotation"):
                    in_annotation = True
                    continue
                elif l.startswith(".end annotation"):
                    in_annotation = False
                    continue
                elif in_annotation:
                    continue
                tmp.append(l)

        classPath = a[:-6]
        for m, methodBody in methods_code_map.items():
            if len(methodBody) == 0:
                continue
            msig = s+ "\n" + classPath + "\n" + m
            super_method_call_index = -1
            prev_lines = []
            for l in methodBody:
                super_method_call_index += 1
                prev_lines.append(l)
                if l.startswith("invoke-direct {p0"):
                    break

            if len(prev_lines) > 2:
                is_interesting = False
                for l in prev_lines[:-1]:
                    if "p0" in l:
                        is_interesting = True
                if is_interesting:
                    h = str(hashlib.md5(msig.encode("utf-8")).hexdigest())
                    with open("ahhhh/"+h, "w") as f:
                        f.write(msig + "\n")
                        f.write("=======================\n")
                        for l in prev_lines:
                            f.write(l + "\n")
                        f.write("=======================\n")
                        for l in methodBody:
                            f.write(l + "\n")

    app_counter += 1
    if app_counter == 10:
        break


