from __future__ import annotations
_A=True
import shutil,zipfile
from pathlib import Path
from admin.services.util import append_log
class ZipIngestError(Exception):0
def extract_zip(zip_path,dest,log_path):
	C=log_path;B=zip_path;A=dest
	if A.exists():shutil.rmtree(A)
	A.mkdir(parents=_A,exist_ok=_A);append_log(C,f"Extracting {B.name} -> {A}")
	try:
		with zipfile.ZipFile(B,'r')as D:
			for E in D.infolist():
				F=Path(E.filename)
				if F.is_absolute()or'..'in F.parts:raise ZipIngestError(f"Unsafe path in zip: {E.filename}")
			D.extractall(A)
	except zipfile.BadZipFile as G:raise ZipIngestError(f"Invalid zip file: {G}")from G
	_flatten_single_root(A);append_log(C,'Zip extraction complete');return A
def _flatten_single_root(dest):
	G='.DS_Store';B=dest;C=[A for A in B.iterdir()if A.name not in{G,'__MACOSX'}]
	for D in B.glob('__MACOSX*'):
		if D.is_dir():shutil.rmtree(D,ignore_errors=_A)
		else:D.unlink(missing_ok=_A)
	C=[A for A in B.iterdir()if A.name!=G]
	if len(C)==1 and C[0].is_dir():
		E=C[0]
		for F in E.iterdir():
			A=B/F.name
			if A.exists():
				if A.is_dir():shutil.rmtree(A)
				else:A.unlink()
			shutil.move(str(F),str(A))
		E.rmdir()
