"""APK Parser - extracts DEX, manifest, native libs from APK (ZIP)."""
import hashlib
import zipfile
from pathlib import Path
from typing import Dict, List
import os
from apk_analyzer.models import APKInfo


class APKParser:
    def __init__(self, apk_path: Path):
        self.apk_path = apk_path

    def parse(self) -> APKInfo:
        info = APKInfo()
        info.file_size_bytes = self.apk_path.stat().st_size
        sha = hashlib.sha256()
        with open(self.apk_path, "rb") as f:
            for chunk in iter(lambda: f.read(65536), b""):
                sha.update(chunk)
        info.signature_sha256 = sha.hexdigest()

        with zipfile.ZipFile(self.apk_path, "r") as zf:
            names = zf.namelist()
            dex_names = sorted(n for n in names if n.endswith(".dex"))
            info.dex_count = len(dex_names)
            info.dex_files = [zf.read(dn) for dn in dex_names]

            if "AndroidManifest.xml" in names:
                info.manifest_data = zf.read("AndroidManifest.xml")

            seen_libs = set()
            for n in names:
                if n.startswith("lib/") and n.endswith(".so"):
                    lib_name = n.split("/")[-1]
                    if lib_name not in seen_libs:
                        seen_libs.add(lib_name)
                        info.native_libs.append(lib_name)

            for n in names:
                if n.startswith("META-INF/") and n.endswith(".version"):
                    key = n[len("META-INF/"):-len(".version")]
                    try:
                        val = zf.read(n).decode("utf-8", errors="ignore").strip()
                        if val:
                            info.metainf_versions[key] = val
                    except Exception:
                        pass
        return info
