import os
import shutil
import urllib.request
import zipfile
import tempfile
import sys
from win32com.shell import shell, shellcon
import pythoncom

MIN_FILES = 1357
MIN_FOLDERS = 77
MIN_SIZE_BYTES = 24_726_221_580  # 23 GB approx

def count_files_and_folders(path):
    total_files = 0
    total_folders = 0
    total_size = 0
    for root, dirs, files in os.walk(path):
        total_files += len(files)
        total_folders += len(dirs)
        for f in files:
            fp = os.path.join(root, f)
            if os.path.isfile(fp):
                total_size += os.path.getsize(fp)
    return total_files, total_folders, total_size

def create_shortcut(target, shortcut_path, description):
    shell_link = pythoncom.CoCreateInstance(
        shell.CLSID_ShellLink, None,
        pythoncom.CLSCTX_INPROC_SERVER, shell.IID_IShellLink
    )
    shell_link.SetPath(target)
    shell_link.SetDescription(description)
    shell_link.SetWorkingDirectory(os.path.dirname(target))
    shell_link.QueryInterface(pythoncom.IID_IPersistFile).Save(shortcut_path, 0)

def download_progress(block_num, block_size, total_size):
    downloaded = block_num * block_size
    pct = downloaded / total_size * 100 if total_size > 0 else 0
    end_char = "\r" if downloaded < total_size else "\n"
    print(f"Downloading: {pct:.2f}% ({downloaded / (1024**3):.2f} GB / {total_size / (1024**3):.2f} GB)", end=end_char)

def extract_with_progress(zip_path, extract_to):
    with zipfile.ZipFile(zip_path, 'r') as zip_ref:
        total_files = len(zip_ref.infolist())
        extracted_files = 0

        for member in zip_ref.infolist():
            zip_ref.extract(member, extract_to)
            extracted_files += 1
            progress = (extracted_files / total_files) * 100
            print(f"\r[⇩] Extracting... {progress:.1f}%", end='', flush=True)
    print("\n[✓] Extraction complete.")

def main():
    if len(sys.argv) < 2:
        print("Usage: python update_spellbreak.py <install_path>")
        sys.exit(1)

    install_dir = sys.argv[1]
    temp_zip = os.path.join(tempfile.gettempdir(), "elefracbase.zip")
    zip_url = "https://cdn.elefrac.com/game/elefracbase.zip"

    # Check if install_dir exists and is valid
    if os.path.isdir(install_dir):
        print(f"[i] Checking existing install folder: {install_dir}")
        files_count, folders_count, total_size = count_files_and_folders(install_dir)
        print(f"[i] Found {files_count} files, {folders_count} folders, {total_size / (1024**3):.2f} GB total")

        if (files_count >= MIN_FILES and
            folders_count >= MIN_FOLDERS and
            total_size >= MIN_SIZE_BYTES):
            print("[✓] Existing install looks complete. Skipping download and extraction.")
        else:
            print("[!] Installation incomplete or missing. Preparing to download and extract.")
            if (not os.path.isfile(temp_zip) or
                os.path.getsize(temp_zip) < 11_105_197_347):  # 10.3 GB check for ZIP
                print("[⇩] Downloading elefracbase.zip...")
                urllib.request.urlretrieve(zip_url, temp_zip, reporthook=download_progress)
                print("\n[✓] Download complete.")
            else:
                print(f"[i] Found existing zip at {temp_zip} ({os.path.getsize(temp_zip)/(1024**3):.2f} GB), skipping download.")

            # Extract ZIP with progress
            print(f"[⇩] Extracting {temp_zip} to {install_dir} ...")
            extract_with_progress(temp_zip, install_dir)import os
import shutil
import urllib.request
import zipfile
import tempfile
import sys
import webbrowser
from win32com.shell import shell, shellcon
import pythoncom

MIN_FILES = 1357
MIN_FOLDERS = 77
MIN_SIZE_BYTES = 24_726_221_580  # 23 GB approx

def count_files_and_folders(path):
    total_files = 0
    total_folders = 0
    total_size = 0
    for root, dirs, files in os.walk(path):
        total_files += len(files)
        total_folders += len(dirs)
        for f in files:
            fp = os.path.join(root, f)
            if os.path.isfile(fp):
                total_size += os.path.getsize(fp)
    return total_files, total_folders, total_size

def create_shortcut(target, shortcut_path, description):
    shell_link = pythoncom.CoCreateInstance(
        shell.CLSID_ShellLink, None,
        pythoncom.CLSCTX_INPROC_SERVER, shell.IID_IShellLink
    )
    shell_link.SetPath(target)
    shell_link.SetDescription(description)
    shell_link.SetWorkingDirectory(os.path.dirname(target))
    shell_link.QueryInterface(pythoncom.IID_IPersistFile).Save(shortcut_path, 0)

def download_progress(block_num, block_size, total_size):
    downloaded = block_num * block_size
    pct = downloaded / total_size * 100 if total_size > 0 else 0
    end_char = "\r" if downloaded < total_size else "\n"
    print(f"Downloading: {pct:.2f}% ({downloaded / (1024**3):.2f} GB / {total_size / (1024**3):.2f} GB)", end=end_char)

def extract_with_progress(zip_path, extract_to):
    with zipfile.ZipFile(zip_path, 'r') as zip_ref:
        total_files = len(zip_ref.infolist())
        extracted_files = 0

        for member in zip_ref.infolist():
            zip_ref.extract(member, extract_to)
            extracted_files += 1
            progress = (extracted_files / total_files) * 100
            print(f"\r[⇩] Extracting... {progress:.1f}%", end='', flush=True)
    print("\n[✓] Extraction complete.")

def download_zip(zip_url, temp_zip):
    try:
        print("[⇩] Downloading elefracbase.zip...")
        urllib.request.urlretrieve(zip_url, temp_zip, reporthook=download_progress)
        print("\n[✓] Download complete.")
    except Exception as e:
        print(f"\n[✗] Download failed: {e}")
        print("Opening browser to manual download page...")
        webbrowser.open("https://sbcommunity.itch.io/spellbreak-community-version")
        sys.exit(1)

def main():
    if len(sys.argv) < 2:
        print("Usage: python update_spellbreak.py <install_path>")
        sys.exit(1)

    install_dir = sys.argv[1]
    temp_zip = os.path.join(tempfile.gettempdir(), "elefracbase.zip")
    zip_url = "https://cdn.elefrac.com/game/elefracbase.zip"

    # Check if install_dir exists and is valid
    if os.path.isdir(install_dir):
        print(f"[i] Checking existing install folder: {install_dir}")
        files_count, folders_count, total_size = count_files_and_folders(install_dir)
        print(f"[i] Found {files_count} files, {folders_count} folders, {total_size / (1024**3):.2f} GB total")

        if (files_count >= MIN_FILES and
            folders_count >= MIN_FOLDERS and
            total_size >= MIN_SIZE_BYTES):
            print("[✓] Existing install looks complete. Skipping download and extraction.")
        else:
            print("[!] Installation incomplete or missing. Preparing to download and extract.")
            if (not os.path.isfile(temp_zip) or
                os.path.getsize(temp_zip) < 11_105_197_347):  # 10.3 GB check for ZIP
                download_zip(zip_url, temp_zip)
            else:
                print(f"[i] Found existing zip at {temp_zip} ({os.path.getsize(temp_zip)/(1024**3):.2f} GB), skipping download.")

            # Extract ZIP with progress
            print(f"[⇩] Extracting {temp_zip} to {install_dir} ...")
            extract_with_progress(temp_zip, install_dir)
    else:
        print("[!] Install directory does not exist. Creating it and downloading.")
        os.makedirs(install_dir)
        if (not os.path.isfile(temp_zip) or
            os.path.getsize(temp_zip) < 11_105_197_347):
            download_zip(zip_url, temp_zip)
        else:
            print(f"[i] Found existing zip at {temp_zip} ({os.path.getsize(temp_zip)/(1024**3):.2f} GB), skipping download.")

        print(f"[⇩] Extracting {temp_zip} to {install_dir} ...")
        extract_with_progress(temp_zip, install_dir)

    # Now create shortcuts regardless
    start_menu_folder = os.path.join(
        os.environ['APPDATA'], r"Microsoft\Windows\Start Menu\Programs\Steam"
    )
    if not os.path.exists(start_menu_folder):
        os.makedirs(start_menu_folder)

    exe_path = os.path.join(install_dir, "Spellbreak.exe")
    shortcut_exe_path = os.path.join(start_menu_folder, "Launch Spellbreak.lnk")
    create_shortcut(exe_path, shortcut_exe_path, "Launch Spellbreak")

    shortcut_doc_path = os.path.join(start_menu_folder, "Spellbreak Documentation.lnk")
    create_shortcut(install_dir, shortcut_doc_path, "Spellbreak Documentation")

    print("[✓] Shortcuts created.")
    print("Done.")

if __name__ == "__main__":
    main()

    else:
        print("[!] Install directory does not exist. Creating it and downloading.")
        os.makedirs(install_dir)
        if (not os.path.isfile(temp_zip) or
            os.path.getsize(temp_zip) < 11_105_197_347):
            print("[⇩] Downloading elefracbase.zip...")
            urllib.request.urlretrieve(zip_url, temp_zip, reporthook=download_progress)
            print("\n[✓] Download complete.")
        else:
            print(f"[i] Found existing zip at {temp_zip} ({os.path.getsize(temp_zip)/(1024**3):.2f} GB), skipping download.")

        print(f"[⇩] Extracting {temp_zip} to {install_dir} ...")
        extract_with_progress(temp_zip, install_dir)

    # Now create shortcuts regardless
    start_menu_folder = os.path.join(
        os.environ['APPDATA'], r"Microsoft\Windows\Start Menu\Programs\Steam"
    )
    if not os.path.exists(start_menu_folder):
        os.makedirs(start_menu_folder)

    exe_path = os.path.join(install_dir, "Spellbreak.exe")
    shortcut_exe_path = os.path.join(start_menu_folder, "Launch Spellbreak.lnk")
    create_shortcut(exe_path, shortcut_exe_path, "Launch Spellbreak")

    shortcut_doc_path = os.path.join(start_menu_folder, "Spellbreak Documentation.lnk")
    create_shortcut(install_dir, shortcut_doc_path, "Spellbreak Documentation")

    print("[✓] Shortcuts created.")
    print("Done.")

if __name__ == "__main__":
    main()
