from __future__ import annotations
import shutil
from pathlib import Path
from admin.services.util import append_log,run_command
class GitIngestError(Exception):0
def clone_or_update(git_url,dest,log_path,branch=None):
	K='--hard';J='reset';H=git_url;F='git';E=branch;D=log_path;A=dest;E=(E or'').strip()or None;A.parent.mkdir(parents=True,exist_ok=True)
	if A.exists()and(A/'.git').is_dir():
		append_log(D,f"Updating existing clone at {A}");C,B=run_command([F,'fetch','--all','--prune'],cwd=A);append_log(D,B)
		if C!=0:raise GitIngestError(f"git fetch failed:\n{B}")
		if E:
			C,B=run_command([F,'checkout',E],cwd=A);append_log(D,B)
			if C!=0:raise GitIngestError(f"git checkout {E} failed:\n{B}")
			C,B=run_command([F,J,K,f"origin/{E}"],cwd=A);append_log(D,B)
			if C!=0:
				L,I=run_command([F,J,K,'HEAD'],cwd=A);append_log(D,I)
				if L!=0:raise GitIngestError(f"git reset failed:\n{B}\n{I}")
		else:
			C,B=run_command([F,'pull','--ff-only'],cwd=A);append_log(D,B)
			if C!=0:raise GitIngestError(f"git pull failed:\n{B}")
		return A
	if A.exists():shutil.rmtree(A)
	append_log(D,f"Cloning {H} -> {A}");G=[F,'clone','--depth','1']
	if E:G+=['--branch',E]
	G+=[H,str(A)];C,B=run_command(G,timeout=600);append_log(D,B)
	if C!=0:raise GitIngestError(f"git clone failed:\n{B}")
	return A
