import os
import sys
import hashlib
import tempfile
import subprocess
import urllib.request
import requests
from win32com.client import Dispatch

def sha256_checksum(filename, block_size=65536):
    sha256 = hashlib.sha256()
    with open(filename, 'rb') as f:
        for block in iter(lambda: f.read(block_size), b''):
            sha256.update(block)
    return sha256.hexdigest()

def get_latest_faf_installer_url():
    api_url = "https://api.github.com/repos/FAForever/downlords-faf-client/releases/latest"
    try:
        response = requests.get(api_url)
        response.raise_for_status()
        release_data = response.json()
        for asset in release_data.get("assets", []):
            name = asset.get("name", "")
            if name.startswith("faf_windows-x64") and name.endswith(".exe"):
                return asset.get("browser_download_url")
    except Exception as e:
        print(f"Failed to fetch latest FAF release: {e}")
    return None

def download_file(url, save_path):
    try:
        print(f"Downloading from {url} ...")
        urllib.request.urlretrieve(url, save_path)
        print(f"Downloaded to {save_path}")
        return True
    except Exception as e:
        print(f"Download failed from {url}: {e}")
        return False

def download_faf_launcher(save_path):
    latest_url = get_latest_faf_installer_url()
    if not latest_url:
        print("No installer URL found.")
        sys.exit(1)

    with tempfile.NamedTemporaryFile(delete=False) as tmp_file:
        tmp_path = tmp_file.name

    if not download_file(latest_url, tmp_path):
        if os.path.exists(tmp_path):
            os.remove(tmp_path)
        sys.exit(1)

    if not os.path.exists(save_path):
        print("No local launcher found, installing new launcher...")
        os.replace(tmp_path, save_path)
        return True

    local_hash = sha256_checksum(save_path)
    new_hash = sha256_checksum(tmp_path)

    if local_hash == new_hash:
        print("Local FAF launcher is up-to-date.")
        os.remove(tmp_path)
        return False

    print("Newer FAF launcher detected, updating...")
    os.replace(tmp_path, save_path)
    return True

def run_launcher(launcher_path, install_dir):
    install_dir = install_dir.rstrip("\\/")
    print(f"Running FAF installer silently in: {install_dir}")
    try:
        subprocess.run([
            launcher_path,
            "-q",
            "-overwrite",
            "-dir", install_dir
        ], check=True)

    except Exception as e:
        print(f"Failed to launch FAF installer: {e}")


def create_shortcut(target_exe, shortcut_name):
    start_menu_dir = os.path.join(os.environ["APPDATA"], "Microsoft", "Windows", "Start Menu", "Programs", "Steam")
    os.makedirs(start_menu_dir, exist_ok=True)
    shortcut_path = os.path.join(start_menu_dir, f"{shortcut_name}.lnk")

    print(f"Creating shortcut: {shortcut_path}")
    shell = Dispatch("WScript.Shell")
    shortcut = shell.CreateShortcut(shortcut_path)
    shortcut.TargetPath = target_exe
    shortcut.WorkingDirectory = os.path.dirname(target_exe)
    shortcut.IconLocation = target_exe
    shortcut.Save()

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Usage: python update_faf.py <install_path>")
        sys.exit(1)

    install_dir = sys.argv[1]
    if not os.path.isdir(install_dir):
        print("Invalid install directory:", install_dir)
        sys.exit(1)

    launcher_path = os.path.join(install_dir, "faf_windows_launcher.exe")
    faf_client_exe = os.path.join(install_dir, "faf-client.exe")

    should_run = download_faf_launcher(launcher_path)

    if should_run:
        run_launcher(launcher_path, install_dir)
        # Wait until the installer finishes, then create the shortcut
        create_shortcut(faf_client_exe, "Supreme Commander Forged Alliance Forever")
    else:
        print("Skipping launcher run since it's up-to-date.")
        # Only create shortcut if the FAF client already exists
        if os.path.exists(faf_client_exe):
            create_shortcut(faf_client_exe, "Supreme Commander: Forged Alliance Forever")
        else:
            print("FAF client not found. Shortcut not created.")
