"""FaceFusion ile yüz değiştirme servisi."""
from __future__ import annotations
from pathlib import Path
import os
import subprocess
import sys

_BU = Path(__file__).resolve()
FACEFUSION_DIZIN = _BU.parent.parent.parent / "FaceFusion"
FF_VENV_PY = FACEFUSION_DIZIN / "venv" / "Scripts" / "python.exe"
FF_SCRIPT = FACEFUSION_DIZIN / "facefusion" / "facefusion.py"
FF_SCRIPT_ALT = FACEFUSION_DIZIN / "facefusion" / "run.py"

_YARATMA_BAYRAGI = 0x08000000 if sys.platform == "win32" else 0


def facefusion_kurulu_mu() -> bool:
    return FF_VENV_PY.exists() and (FF_SCRIPT.exists() or FF_SCRIPT_ALT.exists())


def yuz_degistir(kaynak_yuz: str | Path, hedef_resim: str | Path,
                 cikis: str | Path, timeout: int = 120) -> bool:
    """Hedef resimdeki yüzü kaynak yüz ile değiştirir."""
    if not facefusion_kurulu_mu():
        return False

    script = FF_SCRIPT if FF_SCRIPT.exists() else FF_SCRIPT_ALT

    env = os.environ.copy()
    nvidia_dizin = FACEFUSION_DIZIN / "venv" / "Lib" / "site-packages" / "nvidia"
    ekstra = [str(FACEFUSION_DIZIN / "venv" / "Scripts")]
    if nvidia_dizin.exists():
        for d in nvidia_dizin.iterdir():
            if d.is_dir():
                for alt in ("bin", "lib"):
                    p = d / alt
                    if p.exists():
                        ekstra.append(str(p))
    cuda = r"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.6\bin"
    if os.path.exists(cuda):
        ekstra.append(cuda)
    env["PATH"] = ";".join(ekstra) + ";" + env.get("PATH", "")

    cmd = [
        str(FF_VENV_PY), str(script), "headless-run",
        "--source-paths", str(Path(kaynak_yuz).resolve()),
        "--target-path", str(Path(hedef_resim).resolve()),
        "--output-path", str(Path(cikis).resolve()),
        "--processors", "face_swapper",
        "--execution-providers", "cuda",
        "--face-selector-mode", "one",
        "--face-detector-score", "0.5",
        "--output-image-quality", "95",
    ]

    try:
        subprocess.run(
            cmd, capture_output=True, text=True, timeout=timeout,
            cwd=str(FACEFUSION_DIZIN / "facefusion"), env=env,
            creationflags=_YARATMA_BAYRAGI,
        )
    except Exception:
        return False
    return Path(cikis).exists()
