import os
import subprocess
import requests
from tqdm import tqdm

# Constants
REPO_URL = "https://github.com/Mikubill/sd-webui-controlnet"
TARGET_FOLDER = r"/workspace/stable-diffusion-webui/extensions"
urls = [
    "https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/kohya_controllllite_xl_blur.safetensors",
    "https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/kohya_controllllite_xl_blur_anime.safetensors",
    "https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/kohya_controllllite_xl_blur_anime_beta.safetensors",
    "https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/kohya_controllllite_xl_canny.safetensors",
    "https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/kohya_controllllite_xl_depth.safetensors",
    "https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/t2i-adapter_diffusers_xl_canny.safetensors",
    "https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/t2i-adapter_diffusers_xl_depth_midas.safetensors",
    "https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/t2i-adapter_diffusers_xl_depth_zoe.safetensors",
    "https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/t2i-adapter_diffusers_xl_lineart.safetensors",
    "https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/t2i-adapter_diffusers_xl_openpose.safetensors",
    "https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/t2i-adapter_diffusers_xl_sketch.safetensors",
    "https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11e_sd15_ip2p.pth",
    "https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11e_sd15_shuffle.pth",
    "https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11f1e_sd15_tile.pth",
    "https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11f1p_sd15_depth.pth",
    "https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_canny.pth",
    "https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_inpaint.pth",
    "https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_lineart.pth",
    "https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_mlsd.pth",
    "https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_normalbae.pth",
    "https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_openpose.pth",
    "https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_scribble.pth",
    "https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_seg.pth",
    "https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_softedge.pth",
    "https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15s2_lineart_anime.pth",
    "https://huggingface.co/TencentARC/T2I-Adapter/resolve/main/models/t2iadapter_style_sd14v1.pth",
    "https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/diffusers_xl_canny_full.safetensors",
    "https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/diffusers_xl_depth_full.safetensors",
    "https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/ioclab_sd15_recolor.safetensors",
    "https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/ip-adapter_sd15_plus.pth",
    "https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/ip-adapter_xl.pth",
    "https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/kohya_controllllite_xl_canny_anime.safetensors",
    "https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/kohya_controllllite_xl_depth_anime.safetensors",
    "https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/kohya_controllllite_xl_openpose_anime.safetensors",
    "https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/kohya_controllllite_xl_openpose_anime_v2.safetensors",
    "https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/kohya_controllllite_xl_scribble_anime.safetensors",
    "https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/sai_xl_canny_256lora.safetensors",
    "https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/sai_xl_depth_256lora.safetensors",
    "https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/sai_xl_recolor_256lora.safetensors",
    "https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/sai_xl_sketch_256lora.safetensors",
    "https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/sargezt_xl_depth.safetensors",
    "https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/sargezt_xl_depth_faid_vidit.safetensors",
    "https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/sargezt_xl_depth_zeed.safetensors",
    "https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/sargezt_xl_softedge.safetensors",
    "https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/t2i-adapter_xl_canny.safetensors",
    "https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/t2i-adapter_xl_openpose.safetensors",
    "https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/t2i-adapter_xl_sketch.safetensors",
    "https://huggingface.co/lllyasviel/sd_control_collection/resolve/main/thibaud_xl_openpose.safetensors",
	"https://huggingface.co/h94/IP-Adapter/resolve/main/sdxl_models/ip-adapter-plus-face_sdxl_vit-h.safetensors",
	"https://huggingface.co/h94/IP-Adapter/resolve/main/sdxl_models/ip-adapter-plus_sdxl_vit-h.safetensors"
]

def clone_repo(repo_url, target_folder):
    if not os.path.exists(os.path.join(target_folder, 'sd-webui-controlnet')):
        try:
            subprocess.check_output(['git', 'clone', repo_url], cwd=target_folder)
            print("Git clone completed successfully.")
        except subprocess.CalledProcessError as e:
            print(f"Git clone failed with error:\n{e}")
    else:
        print("Folder already exists. Skipping git clone.")

def git_pull(folder_path):
    try:
        subprocess.check_output(['git', 'pull'], cwd=folder_path)
        print("Git pull completed successfully.")
    except subprocess.CalledProcessError as e:
        print(f"Git pull failed with error:\n{e}")

def git_pull2(folder_path):
    try:
        # Stash any local changes
        subprocess.check_output(['git', 'stash'], cwd=folder_path)
        
        # Checkout the master branch
        subprocess.check_output(['git', 'checkout', 'master'], cwd=folder_path)
        
        # Pull the latest changes
        subprocess.check_output(['git', 'pull'], cwd=folder_path)
        
        print("Git pull completed successfully.")
    except subprocess.CalledProcessError as e:
        print(f"Git pull failed with error:\n{e}")

def download_files(url_list, save_path):
    total_files = len(url_list)
    downloaded_files = 0
    print(f"Downloaded ({downloaded_files}/{total_files})")
    for url in url_list:
        filename = os.path.basename(url)
        filepath = os.path.join(save_path, filename)

        if os.path.exists(filepath):
            downloaded_files += 1
            print(f"Skipped {filename}. Make sure it was fully downloaded! ({downloaded_files}/{total_files})")
            continue

        response = requests.get(url, stream=True)
        total_length = int(response.headers.get("content-length"))
        with open(filepath, "wb") as file, tqdm(
            desc=f"Downloading {filename}", total=total_length, unit="B", unit_scale=True
        ) as progress_bar:
            for data in response.iter_content(chunk_size=4096):
                file.write(data)
                progress_bar.update(len(data))
        
        downloaded_files += 1
        print(f"Downloaded {filename} ({downloaded_files}/{total_files})")

def download_file_from_url(url, save_path):
    """
    Download a file from the given URL and save it to the specified path.
    If the file already exists at the path, it will be overwritten.

    :param url: URL of the file to download
    :param save_path: Local path where the file should be saved
    """
    try:
        response = requests.get(url, stream=True)
        response.raise_for_status()  # Raise an HTTPError if the response contains an unsuccessful status code

        # Ensure the directory for save_path exists
        os.makedirs(os.path.dirname(save_path), exist_ok=True)

        with open(save_path, 'wb') as file:
            for chunk in response.iter_content(chunk_size=8192):
                file.write(chunk)

        print(f"Successfully downloaded: {url}")

    except requests.HTTPError as e:
        print(f"Failed to download {url}. Error: {e}")

if __name__ == "__main__":
    clone_repo(REPO_URL, TARGET_FOLDER)
    git_pull(os.path.join(TARGET_FOLDER, 'sd-webui-controlnet'))
    git_pull2("/workspace/stable-diffusion-webui")
    repo_name = os.path.basename(REPO_URL)
    os.chdir(os.path.join(TARGET_FOLDER, repo_name))

    models_folder = os.path.join(os.getcwd(), "models")
    os.makedirs(models_folder, exist_ok=True)

    download_files(urls, models_folder)
    
    # Additional downloads
    additional_files = [
        ("https://huggingface.co/stabilityai/sdxl-vae/resolve/main/sdxl_vae.safetensors", "/workspace/stable-diffusion-webui/models/VAE/sdxl_vae.safetensors"),
        ("https://huggingface.co/MonsterMMORPG/SECourses/resolve/main/webui-user-pt1.sh", "/workspace/stable-diffusion-webui/webui-user.sh")
    ]

    for url, save_path in additional_files:
        download_file_from_url(url, save_path)
    
    print("All files downloaded successfully.")
