import logging
import os
import subprocess
import xml.etree.ElementTree as ET

from androguard.misc import AnalyzeAPK


def decompile_apk(apk_path, output_dir):
    """Decompile APK using APKTool"""
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    command = f"apktool d -f {apk_path} -o {output_dir}"
    subprocess.run(command, shell=True, check=True)
    logging.info(f"[+] APK decompiled to: {output_dir}")


def extract_source_code(apk_path, output_dir):
    """Extract source code using Jadx"""
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    command = f"jadx -d {output_dir} {apk_path}"
    subprocess.run(command, shell=True, check=True)
    logging.info(f"[+] Source code extracted to: {output_dir}")


def analyze_permissions(apk_path):
    """Analyze APK permissions using Androguard"""
    a, _, _ = AnalyzeAPK(apk_path)
    permissions = a.get_permissions()

    logging.info("[+] Requested Permissions:")
    for perm in permissions:
        logging.info(f" - {perm}")


def search_for_vulnerabilities(source_code_dir):
    """Search for common vulnerabilities in the source code"""
    common_vulns = [
        "Runtime.exec(",
        "getSharedPreferences(",
        "HttpURLConnection",
        "SSLSocketFactory",
        "setAllowBackup(true)",
        "setDebug(true)",
    ]

    logging.info("[+] Searching for common vulnerabilities:")
    for root, _, files in os.walk(source_code_dir):
        for file in files:
            if file.endswith(".java"):
                file_path = os.path.join(root, file)
                with open(file_path, "r", encoding="utf-8") as f:
                    lines = f.readlines()
                    for line_num, line in enumerate(lines, 1):
                        for vuln in common_vulns:
                            if vuln in line:
                                logging.warning(
                                    f" - {file_path}:{line_num} - {line.strip()}"
                                )


def analyze_android_manifest(decompiled_dir):
    """Analyze AndroidManifest.xml for insecure settings"""
    manifest_path = os.path.join(decompiled_dir, "AndroidManifest.xml")
    if not os.path.exists(manifest_path):
        logging.error("[-] AndroidManifest.xml file not found!")
        return

    tree = ET.parse(manifest_path)
    root = tree.getroot()

    logging.info("[+] Analyzing AndroidManifest.xml:")

    # Look for insecure settings
    insecure_settings = {
        "android:allowBackup": "true",
        "android:debuggable": "true",
        "android:usesCleartextTraffic": "true",
    }

    for element in root.iter():
        for attr, value in insecure_settings.items():
            if element.get(attr) == value:
                logging.warning(f" - {element.tag}: {attr}={value} (Insecure)")


def scan_apk(apk_path):
    """Perform a complete APK security scan"""
    decompiled_dir = "decompiled_apk"
    source_code_dir = "source_code"

    decompile_apk(apk_path, decompiled_dir)
    extract_source_code(apk_path, source_code_dir)
    analyze_permissions(apk_path)
    analyze_android_manifest(decompiled_dir)
    search_for_vulnerabilities(source_code_dir)

    logging.info("[+] Scan completed successfully!")
