#!/usr/bin/env python3
# Copyright 2019 The Emscripten Authors.  All rights reserved.
# Emscripten is available under two separate licenses, the MIT license and the
# University of Illinois/NCSA Open Source License.  Both these licenses can be
# found in the LICENSE file.

import copy
import json
import multiprocessing
import os
import os.path
import platform
import re
import shutil
import stat
import subprocess
import sys
import sysconfig
import tarfile
import zipfile

if os.name == 'nt':
    import ctypes.wintypes
    import winreg

from urllib.parse import urljoin
from urllib.request import urlopen

if sys.version_info < (3, 10):  # ruff: ignore[outdated-version-block]
    print(f'error: emsdk requires python 3.10 or above ({sys.executable} {sys.version})', file=sys.stderr)
    sys.exit(1)

emsdk_packages_url = 'https://storage.googleapis.com/webassembly/emscripten-releases-builds/deps/'

emscripten_releases_repo = 'https://chromium.googlesource.com/emscripten-releases'

emscripten_releases_download_url_template = "https://storage.googleapis.com/webassembly/emscripten-releases-builds/%s/%s/wasm-binaries%s.%s"

# This was previously `master.zip` but we are transitioning to `main` and
# `HEAD.zip` works for both cases.  In future we could switch this to
# `main.zip` perhaps.
emsdk_zip_download_url = 'https://github.com/emscripten-core/emsdk/archive/HEAD.zip'

download_dir = 'downloads/'

extra_release_tag = None


def get_env_boolean(name):
    env_var = os.getenv(name)
    assert env_var in {None, '1', '0'}, f'invalid environment variable setting ${env_var} for ${name}'
    return env_var == '1'


# Enable this to do very verbose printing about the different steps that are
# being run. Useful for debugging.
VERBOSE = get_env_boolean('EMSDK_VERBOSE')
QUIET = get_env_boolean('EMSDK_QUIET')
if get_env_boolean('EMSDK_NOTTY'):
    TTY_OUTPUT = False
else:
    TTY_OUTPUT = sys.stdout.isatty()


def info(msg):
    if not QUIET:
        print(msg, file=sys.stderr)


def errlog(msg):
    print(msg, file=sys.stderr)


def exit_with_error(msg):
    errlog(f'error: {msg}')
    sys.exit(1)


WINDOWS = False
MINGW = False
MSYS = False
MACOS = False
LINUX = False

os_override = os.environ.get('EMSDK_OS')
if os_override:
    if os_override == 'windows':
        WINDOWS = True
    elif os_override == 'linux':
        LINUX = True
    elif os_override == 'macos':
        MACOS = True
    else:
        assert False, 'EMSDK_OS must be one of: windows, linux, macos'
else:
    if os.name == 'nt' or ('windows' in os.getenv('SYSTEMROOT', '').lower()) or ('windows' in os.getenv('COMSPEC', '').lower()):
        WINDOWS = True

    msystem = os.getenv('MSYSTEM')
    if msystem:
        MSYS = True
        # Some functions like os.path.normpath() exhibit different behavior between
        # different versions of Python, so we need to distinguish between the MinGW
        # and MSYS versions of Python
        if sysconfig.get_platform() == 'mingw':
            MINGW = True
        if msystem not in {'MSYS', 'MINGW64'}:
            # https://stackoverflow.com/questions/37460073/msys-vs-mingw-internal-environment-variables
            errlog(f'Warning: MSYSTEM environment variable is present, and is set to "{msystem}". '
                   'This shell has not been tested with emsdk and may not work.')

    if platform.mac_ver()[0]:
        MACOS = True

    if not MACOS and (platform.system() == 'Linux'):
        LINUX = True

UNIX = (MACOS or LINUX)


# Pick which shell of 4 shells to use
POWERSHELL = get_env_boolean('EMSDK_POWERSHELL')
CSH = get_env_boolean('EMSDK_CSH')
CMD = get_env_boolean('EMSDK_CMD')
BASH = get_env_boolean('EMSDK_BASH')
FISH = get_env_boolean('EMSDK_FISH')

if WINDOWS and BASH:
    MSYS = True

if not CSH and not POWERSHELL and not BASH and not CMD and not FISH:
    # Fall back to default of `cmd` on windows and `bash` otherwise
    if WINDOWS and not MSYS:
        CMD = True
    else:
        BASH = True

if WINDOWS:
    ENVPATH_SEPARATOR = ';'
else:
    ENVPATH_SEPARATOR = ':'

# platform.machine() may return AMD64 on windows, so standardize the case.
machine = os.getenv('EMSDK_ARCH', platform.machine().lower())
if machine.startswith(('x64', 'amd64', 'x86_64')):
    ARCH = 'x86_64'
elif machine.endswith('86'):
    ARCH = 'x86'
elif machine.startswith('aarch64') or machine.lower().startswith('arm64'):
    ARCH = 'arm64'
elif machine.startswith('arm'):
    ARCH = 'arm'
else:
    exit_with_error('unknown machine architecture: ' + machine)


# Don't saturate all cores to not steal the whole system, but be aggressive.
CPU_CORES = int(os.getenv('EMSDK_NUM_CORES', max(multiprocessing.cpu_count() - 1, 1)))

CMAKE_BUILD_TYPE_OVERRIDE = None

# If true, perform a --shallow clone of git.
GIT_CLONE_SHALLOW = False

# If true, LLVM backend is built with tests enabled, and Binaryen is built with
# Visual Studio static analyzer enabled.
BUILD_FOR_TESTING = False

# If 'auto', assertions are decided by the build type
# (Release&MinSizeRel=disabled, Debug&RelWithDebInfo=enabled)
# Other valid values are 'ON' and 'OFF'
ENABLE_LLVM_ASSERTIONS = 'auto'

# If true, keeps the downloaded archive files.
KEEP_DOWNLOADS = get_env_boolean('EMSDK_KEEP_DOWNLOADS')


def os_name_short():
    if WINDOWS:
        return 'win'
    elif LINUX:
        return 'linux'
    elif MACOS:
        return 'mac'
    assert False, 'unknown OS'


def os_name():
    if WINDOWS:
        return 'windows'
    if LINUX:
        return 'linux'
    if MACOS:
        return 'macos'
    assert False, 'unknown OS'


def debug_print(msg):
    if VERBOSE:
        errlog(msg)


def to_unix_path(p):
    return p.replace('\\', '/')


EMSDK_PATH = to_unix_path(os.path.dirname(os.path.realpath(__file__)))

EMSDK_SET_ENV = ""
if POWERSHELL:
    EMSDK_SET_ENV = os.path.join(EMSDK_PATH, 'emsdk_set_env.ps1')
else:
    EMSDK_SET_ENV = os.path.join(EMSDK_PATH, 'emsdk_set_env.bat')


def parse_github_url_and_refspec(url):
    """Parse a github URL a tuple of its components.

    Parses https://github.com/emscripten-core/emscripten/tree/d6aced8 to the
    tuple (https://github.com/emscripten-core/emscripten, d6aced8, emscripten-core)
    or https://github.com/emscripten-core/emscripten/commit/00b76f81f6474113fcf540db69297cfeb180347e
    to (https://github.com/emscripten-core/emscripten, 00b76f81f6474113fcf540db69297cfeb180347e, emscripten-core)
    """
    if not url:
        return ('', '', None)

    if url.endswith(('/tree/', '/tree', '/commit/', '/commit')):
        raise Exception(f'Malformed git URL and refspec {url}!')

    if '/tree/' in url:
        if url.endswith('/'):
            raise Exception(f'Malformed git URL and refspec {url}!')
        url, refspec = url.split('/tree/')
        remote_name = url.split('/')[-2]
        return (url, refspec, remote_name)
    elif '/commit/' in url:
        if url.endswith('/'):
            raise Exception(f'Malformed git URL and refspec {url}!')
        url, refspec = url.split('/commit/')
        remote_name = url.split('/')[-2]
        return (url, refspec, remote_name)
    else:
        return (url, 'main', None)  # Assume the default branch is main in the absence of a refspec


ARCHIVE_SUFFIXES = ('zip', '.tar', '.gz', '.xz', '.tbz2', '.bz2')


def vswhere(version):
    program_files = os.getenv('ProgramFiles(x86)')
    if not program_files:
        program_files = os.environ['ProgramFiles']
    vswhere_path = os.path.join(program_files, 'Microsoft Visual Studio', 'Installer', 'vswhere.exe')
    # Source: https://learn.microsoft.com/en-us/visualstudio/install/workload-component-id-vs-build-tools?view=vs-2022
    tools_arch = 'ARM64' if ARCH == 'arm64' else 'x86.x64'
    try:
        # The "-products *" allows detection of Build Tools, the "-prerelease" allows detection of Preview version
        # of Visual Studio and Build Tools.
        stdout = run_get_output([vswhere_path, '-latest', '-products', '*',
                                 '-prerelease', '-version', f'[{version}.0,{version + 1}.0)',
                                 '-requires', 'Microsoft.VisualStudio.Component.VC.Tools.' + tools_arch,
                                 '-property', 'installationPath', '-format', 'json'])
        json_output = json.loads(stdout)
        return str(json_output[0]['installationPath'])
    except Exception:
        return ''


CMAKE_GENERATOR = 'Unix Makefiles'
if WINDOWS:
    # Detect which CMake generator to use when building on Windows
    if '--mingw' in sys.argv:
        CMAKE_GENERATOR = 'MinGW Makefiles'
    elif '--vs2022' in sys.argv:
        CMAKE_GENERATOR = 'Visual Studio 17'
    elif '--vs2019' in sys.argv:
        CMAKE_GENERATOR = 'Visual Studio 16'
    elif vswhere(17):
        CMAKE_GENERATOR = 'Visual Studio 17'
    elif vswhere(16):
        CMAKE_GENERATOR = 'Visual Studio 16'
    elif shutil.which('mingw32-make') is not None and shutil.which('g++') is not None:
        CMAKE_GENERATOR = 'MinGW Makefiles'
    else:
        # No detected generator
        CMAKE_GENERATOR = ''


sys.argv = [a for a in sys.argv if a not in {'--mingw', '--vs2019', '--vs2022'}]


def cmake_generator_prefix():
    """Computes a suitable path prefix to use when building with a given generator."""
    if CMAKE_GENERATOR == 'Visual Studio 17':
        return '_vs2022'
    if CMAKE_GENERATOR == 'Visual Studio 16':
        return '_vs2019'
    elif CMAKE_GENERATOR == 'MinGW Makefiles':
        return '_mingw'
    # Unix Makefiles do not specify a path prefix for backwards path compatibility
    return ''


def remove_tree(d):
    """Removes a directory tree even if it was readonly, and doesn't throw exception
    on failure.
    """
    debug_print(f'remove_tree({d})')
    if not os.path.exists(d):
        return
    try:
        def remove_readonly_and_try_again(func, path, exc_info):
            if not (os.stat(path).st_mode & stat.S_IWRITE):
                os.chmod(path, stat.S_IWRITE)
                func(path)
            else:
                raise exc_info[1]
        shutil.rmtree(d, onerror=remove_readonly_and_try_again)
    except Exception as e:
        debug_print('remove_tree threw an exception, ignoring: ' + str(e))


def win_set_environment_variable_direct(key, value, system=True):
    folder = None
    try:
        if system:
            # Read globally from ALL USERS section.
            folder = winreg.OpenKeyEx(winreg.HKEY_LOCAL_MACHINE, 'SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment', 0, winreg.KEY_ALL_ACCESS)
        else:
            # Register locally from CURRENT USER section.
            folder = winreg.OpenKeyEx(winreg.HKEY_CURRENT_USER, 'Environment', 0, winreg.KEY_ALL_ACCESS)
        winreg.SetValueEx(folder, key, 0, winreg.REG_EXPAND_SZ, value)
        debug_print(f'Set key={key} with value {value} in registry.')
        return True
    except Exception as e:
        # 'Access is denied.'
        if e.args[3] == 5:
            exit_with_error(f"failed to set the environment variable '{key}'! "
                            'Setting environment variables permanently requires administrator access. '
                            'Please rerun this command with administrative privileges. '
                            'This can be done for example by holding down the Ctrl and Shift keys '
                            'while opening a command prompt in start menu.')
        errlog(f'Failed to write environment variable {key}:')
        errlog(str(e))
        return False
    finally:
        if folder is not None:
            folder.Close()


def win_get_environment_variable(key, system=True, user=True, fallback=True):
    if (not system and not user and fallback):
        # if no --system or --permanent flag is provided use shell's value
        return os.environ[key]
    try:
        folder = None
        try:
            if system:
                # Read globally from ALL USERS section.
                folder = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, 'SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment')
            else:
                # Register locally from CURRENT USER section.
                folder = winreg.OpenKey(winreg.HKEY_CURRENT_USER, 'Environment')
            value = str(winreg.QueryValueEx(folder, key)[0])
        except Exception:
            # If reading registry fails for some reason - read via os.environ. This has the drawback
            # that expansion items such as %PROGRAMFILES% will have been expanded, so
            # need to be precise not to set these back to system registry, or
            # expansion items would be lost.
            if fallback:
                return os.environ[key]
            return None
        finally:
            if folder is not None:
                folder.Close()

    except Exception as e:
        # this catch is if both the registry key threw an exception and the key is not in os.environ
        if e.args[0] != 2:
            # 'The system cannot find the file specified.'
            errlog(f'Failed to read environment variable {key}:')
            errlog(str(e))
        return None
    return value


def win_set_environment_variable(key, value, system, user):
    debug_print(f'set {key}={value}, in system={system}')
    previous_value = win_get_environment_variable(key, system=system, user=user)
    if previous_value == value:
        debug_print('  no need to set, since same value already exists.')
        # No need to elevate UAC for nothing to set the same value, skip.
        return False

    if not value:
        try:
            if system:
                cmd = ['REG', 'DELETE', 'SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment', '/V', key, '/f']
            else:
                cmd = ['REG', 'DELETE', 'HKCU\\Environment', '/V', key, '/f']
            debug_print(str(cmd))
            subprocess.call(cmd, stdout=subprocess.PIPE)
        except Exception:
            return False
        return True

    try:
        if win_set_environment_variable_direct(key, value, system):
            return True
        # Escape % signs so that we don't expand references to environment variables.
        value = value.replace('%', '^%')
        if len(value) >= 1024:
            exit_with_error(f'the new environment variable {key} is more than 1024 characters long! '
                            'A value this long cannot be set via command line: please add the environment variable '
                            'specified above to system environment manually via Control Panel.')
        cmd = ['SETX', key, value]
        debug_print(str(cmd))
        retcode = subprocess.call(cmd, stdout=subprocess.PIPE)
        if retcode != 0:
            errlog(f'ERROR! Failed to set environment variable {key}={value}. You may need to set it manually.')
        else:
            return True
    except Exception as e:
        errlog(f'ERROR! Failed to set environment variable {key}={value}:')
        errlog(str(e))
        errlog('You may need to set it manually.')

    return False


def win_set_environment_variables(env_vars_to_add, system, user):
    if not env_vars_to_add:
        return

    changed = False

    for key, value in env_vars_to_add:
        if win_set_environment_variable(key, value, system, user):
            if not changed:
                changed = True
                print('Setting global environment variables:')

            print(f'{key} = {value}')

    if not changed:
        print('Global environment variables up to date')
        return

    # if changes were made then we need to notify other processes
    try:
        HWND_BROADCAST = ctypes.wintypes.HWND(0xFFFF)  # win32con.HWND_BROADCAST == 65535
        WM_SETTINGCHANGE = 0x001A  # win32con.WM_SETTINGCHANGE == 26
        SMTO_BLOCK = 0x0001  # win32con.SMTO_BLOCK == 1
        ctypes.windll.user32.SendMessageTimeoutA(
          HWND_BROADCAST,    # hWnd: notify everyone
          WM_SETTINGCHANGE,  # Msg: registry changed
          0,                 # wParam: Must be 0 when setting changed is sent by users
          'Environment',     # lParam: Specifically environment variables changed
          SMTO_BLOCK,        # fuFlags: Wait for message to be sent or timeout
          100)               # uTimeout: 100ms
    except Exception as e:
        errlog('SendMessageTimeout failed with error: ' + str(e))


def win_delete_environment_variable(key, system=True, user=True):
    debug_print(f'win_delete_environment_variable(key={key}, system={system})')
    return win_set_environment_variable(key, None, system, user)


def sdk_path(path):
    """Returns the absolute pathname to the given path inside the Emscripten SDK."""
    if os.path.isabs(path):
        return path

    return to_unix_path(os.path.join(EMSDK_PATH, path))


def rmfile(filename):
    """Removes a single file, suppressing exceptions on failure."""
    debug_print(f'rmfile({filename})')
    if os.path.lexists(filename):
        os.remove(filename)


def mkdir_p(path):
    debug_print(f'mkdir_p({path})')
    os.makedirs(path, exist_ok=True)


def is_nonempty_directory(path):
    if not os.path.isdir(path):
        return False
    return len(os.listdir(path)) != 0


def run(cmd, cwd=None, check=True):
    debug_print(f'run(cmd={cmd}, cwd={cwd})')
    returncode = subprocess.call(cmd, cwd=cwd, env=os.environ.copy())
    if returncode != 0 and check:
        errlog(f'{cmd} failed with error code {returncode}')
    return returncode


def untargz(source_filename, dest_dir):
    print(f"Unpacking '{source_filename}' to '{dest_dir}'")
    mkdir_p(dest_dir)
    returncode = run(['tar', '-xvf' if VERBOSE else '-xf', sdk_path(source_filename), '--strip', '1'], cwd=dest_dir)
    # tfile = tarfile.open(source_filename, 'r:gz')
    # tfile.extractall(dest_dir)
    return returncode == 0


def fix_potentially_long_windows_pathname(pathname):
    """Convert pathname to use extended-length path prefix on windows.

    On Windows, it is not possible to reference path names that are longer than
    ~260 characters, unless the path is referenced via a "\\?\" prefix.
    See https://msdn.microsoft.com/en-us/library/aa365247.aspx#maxpath and
    http://stackoverflow.com/questions/3555527/python-win32-filename-length-workaround
    In that mode, forward slashes cannot be used as delimiters.
    """
    if (not WINDOWS or MSYS) or os_override:
        return pathname
    # Test if emsdk calls fix_potentially_long_windows_pathname() with long
    # relative paths (which is problematic)
    if not os.path.isabs(pathname) and len(pathname) > 200:
        errlog(f'Warning: Seeing a relative path "{pathname}" which is dangerously long '
               'for being referenced as a short Windows path name. Refactor emsdk to be able to handle this!')
    if pathname.startswith('\\\\?\\'):
        return pathname
    pathname = os.path.normpath(pathname.replace('/', '\\'))
    if MINGW:
        # MinGW versions of Python return normalized paths with backslashes
        # converted to forward slashes, so we must use forward slashes in our
        # prefix
        return '//?/' + pathname
    return '\\\\?\\' + pathname


def move_with_overwrite(src, dest):
    """On windows, rename/move will fail if the destination exists, and there is no
    race-free way to do it. This method removes the destination if it exists, so
    the move always works
    """
    if os.path.exists(dest):
        os.remove(dest)
    os.rename(src, dest)


# http://stackoverflow.com/questions/12886768/simple-way-to-unzip-file-in-python-on-all-oses
def unzip(source_filename, dest_dir):
    print(f"Unpacking '{source_filename}' to '{dest_dir}'")
    mkdir_p(dest_dir)
    common_subdir = None
    try:
        with zipfile.ZipFile(source_filename) as zf:
            # Implement '--strip 1' behavior to unzipping by testing if all the files
            # in the zip reside in a common subdirectory, and if so, we move the
            # output tree at the end of uncompression step.
            for member in zf.infolist():
                words = member.filename.split('/')
                if len(words) > 1:  # If there is a directory component?
                    if common_subdir is None:
                        common_subdir = words[0]
                    elif common_subdir != words[0]:
                        common_subdir = None
                        break
                else:
                    common_subdir = None
                    break

            unzip_to_dir = dest_dir
            if common_subdir:
                unzip_to_dir = os.path.join(os.path.dirname(dest_dir), 'unzip_temp')

            # Now do the actual decompress.
            unzip_to_dir = fix_potentially_long_windows_pathname(unzip_to_dir)
            for member in zf.infolist():
                zf.extract(member, unzip_to_dir)
                dst_filename = os.path.join(unzip_to_dir, os.path.normpath(member.filename))

                # See: https://stackoverflow.com/questions/42326428/zipfile-in-python-file-permission
                unix_attributes = member.external_attr >> 16
                if unix_attributes:
                    os.chmod(dst_filename, unix_attributes)

                # Move the extracted file to its final location without the base
                # directory name, if we are stripping that away.
                if common_subdir:
                    assert member.filename.startswith(common_subdir), f'unexpected filename {member.filename}'
                    stripped_filename = '.' + member.filename[len(common_subdir):]
                    final_dst_filename = os.path.join(dest_dir, stripped_filename)
                    # Check if a directory
                    if stripped_filename.endswith('/'):
                        d = fix_potentially_long_windows_pathname(final_dst_filename)
                        if not os.path.isdir(d):
                            os.mkdir(d)
                    else:
                        parent_dir = os.path.dirname(fix_potentially_long_windows_pathname(final_dst_filename))
                        if parent_dir and not os.path.exists(parent_dir):
                            os.makedirs(parent_dir)
                        move_with_overwrite(fix_potentially_long_windows_pathname(dst_filename), fix_potentially_long_windows_pathname(final_dst_filename))

            if common_subdir:
                remove_tree(unzip_to_dir)
    except zipfile.BadZipfile as e:
        errlog(f"Unzipping file '{source_filename}' failed due to reason: {e}! Removing the corrupted zip file.")
        rmfile(source_filename)
        return False
    except Exception as e:
        errlog(f"Unzipping file '{source_filename}' failed due to reason: {e}")
        return False

    return True


def path_points_to_directory(path):
    """This function interprets whether the given string looks like a path to a
    directory instead of a file, without looking at the actual filesystem.
    'a/b/c' points to directory, so does 'a/b/c/', but 'a/b/c.x' is parsed as a
    filename
    """
    if path == '.':
        return True
    last_slash = max(path.rfind('/'), path.rfind('\\'))
    last_dot = path.rfind('.')
    no_suffix = last_dot < last_slash or last_dot == -1
    if no_suffix:
        return True
    suffix = path[last_dot:]
    # Very simple logic for the only file suffixes used by emsdk downloader. Other
    # suffixes, like 'clang-3.2' are treated as dirs.
    if suffix in {'.exe', '.zip', '.txt'}:
        return False
    else:
        return True


def get_content_length(download):
    try:
        return int(download.headers.get('Content-Length', 0))
    except ValueError:
        return 0


def get_download_target(url, dstpath, filename_prefix=''):
    file_name = filename_prefix + url.split('/')[-1]
    if path_points_to_directory(dstpath):
        file_name = os.path.join(dstpath, file_name)
    else:
        file_name = dstpath

    # Treat all relative destination paths as relative to the SDK root directory,
    # not the current working directory.
    file_name = sdk_path(file_name)

    return file_name


def download_with_curl(url, file_name):
    print(f"Downloading: {file_name} from {url}")
    if not shutil.which('curl'):
        exit_with_error('curl not found in PATH')
    # -#: show progress bar
    # -L: Follow HTTP 3XX redirections
    # -f: Fail on HTTP errors
    subprocess.check_call(['curl', '-#', '-f', '-L', '-o', file_name, url])


def download_with_urllib(url, file_name):
    u = urlopen(url)
    file_size = get_content_length(u)
    if file_size > 0:
        print(f"Downloading: {file_name} from {url}, {file_size} Bytes")
    else:
        print(f"Downloading: {file_name} from {url}")

    file_size_dl = 0
    # Draw a progress bar 80 chars wide (in non-TTY mode)
    progress_max = 80 - 4
    progress_shown = 0
    block_sz = 256 * 1024
    if not TTY_OUTPUT:
        print(' [', end='')

    with open(file_name, 'wb') as f:
        while True:
            buffer = u.read(block_sz)
            if not buffer:
                break

            file_size_dl += len(buffer)
            f.write(buffer)
            if file_size:
                percent = file_size_dl * 100.0 / file_size
                if TTY_OUTPUT:
                    status = f' {file_size_dl:10d}  [{percent:3.02f}%]'
                    print(status, end='\r')
                else:
                    while progress_shown < progress_max * percent / 100:
                        print('-', end='')
                        sys.stdout.flush()
                        progress_shown += 1

    if not TTY_OUTPUT:
        print(']')
        sys.stdout.flush()

    debug_print(f'finished downloading ({file_size_dl} bytes)')


def download_file(url, dstpath, filename_prefix=''):
    """On success, returns the filename on the disk pointing to the destination file that was produced
    On failure, returns None.
    """
    debug_print(f'download_file(url={url}, dstpath={dstpath})')
    file_name = get_download_target(url, dstpath, filename_prefix)

    if KEEP_DOWNLOADS and os.path.exists(file_name):
        print(f"File '{file_name}' already downloaded, skipping.")
        return file_name

    mkdir_p(os.path.dirname(file_name))

    try:
        # Use curl on macOS or when EMSDK_USE_CURL is set to avoid
        # CERTIFICATE_VERIFY_FAILED issue with python's urllib:
        # https://stackoverflow.com/questions/40684543/how-to-make-python-use-ca-certificates-from-mac-os-truststore
        # Unlike on linux or windows, curl is always available on macOS systems.
        if MACOS or 'EMSDK_USE_CURL' in os.environ:
            download_with_curl(url, file_name)
        else:
            download_with_urllib(url, file_name)
    except Exception as e:
        errlog(f"Error: Downloading URL '{url}': {e}")
        return None
    except KeyboardInterrupt:
        rmfile(file_name)
        raise

    return file_name


def run_get_output(cmd, cwd=None):
    debug_print(f'run_get_output(cmd={cmd}, cwd={cwd})')
    return subprocess.check_output(cmd, cwd=cwd, text=True)


def GIT():
    git = shutil.which('git')
    if not git:
        msg = 'git executable was not found. Please install git for this operation!'
        if WINDOWS:
            msg += "This can be done from http://git-scm.com/"
        elif MACOS:
            msg += "This can be done from http://git-scm.com/, or by installing XCode and then the XCode Command Line Tools"
        elif LINUX:
            msg += "This can be probably be done using your package manager, see http://git-scm.com/book/en/Getting-Started-Installing-Git"
        exit_with_error(msg)

    return git


def git_repo_version(repo_path):
    stdout = run_get_output([GIT(), 'log', '-n', '1', '--pretty="%aD %H"'], cwd=repo_path)
    return stdout.strip()


def git_recent_commits(repo_path, n=20):
    stdout = run_get_output([GIT(), 'log', '-n', str(n), '--pretty="%H"'], cwd=repo_path)
    return stdout.strip().replace('\r', '').replace('"', '').split('\n')


def get_git_remotes(repo_path):
    remotes = []
    output = run_get_output([GIT(), 'remote', '-v'], cwd=repo_path)
    for line in output.splitlines():
        remotes += [line.split()[0]]
    return remotes


def git_clone(url, dstpath, branch, remote_name='origin'):
    debug_print(f'git_clone(url={url}, dstpath={dstpath})')
    if os.path.exists(os.path.join(dstpath, '.git')):
        remotes = get_git_remotes(dstpath)
        if remote_name in remotes:
            debug_print(f'Repository {url} with remote "{remote_name}" already cloned to directory {dstpath}, skipping.')
            return True
        else:
            debug_print(f'Repository {url} with remote "{remote_name}" already cloned to directory {dstpath}, but remote has not yet been added. Creating.')
            return run([GIT(), 'remote', 'add', remote_name, url], cwd=dstpath) == 0

    mkdir_p(dstpath)
    git_clone_args = ['--recurse-submodules', '--branch', branch]  # Do not check out a branch (installer will issue a checkout command right after)
    if GIT_CLONE_SHALLOW:
        git_clone_args += ['--depth', '1']
    print(f'Cloning from {url}...')
    return run([GIT(), 'clone', '-o', remote_name, *git_clone_args, url, dstpath]) == 0


def git_pull(repo_path, branch_or_tag, remote_name='origin'):
    debug_print(f'git_pull(repo_path={repo_path}, branch/tag={branch_or_tag}, remote_name={remote_name})')
    ret = run([GIT(), 'fetch', '--quiet', remote_name], repo_path)
    if ret != 0:
        return False
    try:
        print(f"Fetching latest changes to the branch/tag '{branch_or_tag}' for '{repo_path}'...")
        ret = run([GIT(), 'fetch', '--quiet', remote_name], repo_path)
        if ret != 0:
            return False
        # Test if branch_or_tag is a branch, or if it is a tag that needs to be updated
        target_is_tag = run([GIT(), 'symbolic-ref', '-q', 'HEAD'], repo_path, check=False)

        if target_is_tag:
            ret = run([GIT(), 'checkout', '--recurse-submodules', '--quiet', branch_or_tag], repo_path)
        else:
            local_branch_prefix = (remote_name + '_') if remote_name != 'origin' else ''
            ret = run([GIT(), 'checkout', '--recurse-submodules', '--quiet', '-B', local_branch_prefix + branch_or_tag,
                       '--track', remote_name + '/' + branch_or_tag], repo_path)
        if ret != 0:
            return False
        if not target_is_tag:
            # update branch to latest (not needed for tags)
            # this line assumes that the user has not gone and made local changes to the repo
            ret = run([GIT(), 'merge', '--ff-only', remote_name + '/' + branch_or_tag], repo_path)
        if ret != 0:
            return False
        run([GIT(), 'submodule', 'update', '--init'], repo_path, check=False)
    except Exception:
        errlog('git operation failed!')
        return False
    print(f"Successfully updated and checked out branch/tag '{branch_or_tag}' on repository '{repo_path}'")
    print("Current repository version: " + git_repo_version(repo_path))
    return True


def git_clone_checkout_and_pull(url, dstpath, branch, override_remote_name='origin'):
    debug_print(f'git_clone_checkout_and_pull(url={url}, dstpath={dstpath}, branch={branch}, override_remote_name={override_remote_name})')

    # Make sure the repository is cloned first
    success = git_clone(url, dstpath, branch, override_remote_name)
    if not success:
        return False

    # And/or issue a pull/checkout to get to latest code.
    return git_pull(dstpath, branch, override_remote_name)


def decide_cmake_build_type(tool):
    """Each tool can have its own build type, or it can be overridden on the command
    line.
    """
    if CMAKE_BUILD_TYPE_OVERRIDE:
        return CMAKE_BUILD_TYPE_OVERRIDE
    else:
        return tool.cmake_build_type


def llvm_build_dir(tool):
    """The root directory of the build."""
    generator_suffix = cmake_generator_prefix()
    bitness_suffix = '_32' if tool.bitness == 32 else '_64'

    if tool.git_branch:
        build_dir = 'build_' + tool.git_branch.replace(os.sep, '-') + generator_suffix + bitness_suffix
    else:
        build_dir = 'build_' + tool.version + generator_suffix + bitness_suffix
    return build_dir


def exe_suffix(filename):
    if WINDOWS and not filename.endswith('.exe'):
        filename += '.exe'
    return filename


def llvm_build_bin_dir(tool):
    """The directory where the binaries are produced. (relative to the installation
    root directory of the tool)
    """
    build_dir = llvm_build_dir(tool)
    if WINDOWS and 'Visual Studio' in CMAKE_GENERATOR:
        old_llvm_bin_dir = os.path.join(build_dir, 'bin', decide_cmake_build_type(tool))

        new_llvm_bin_dir = None
        default_cmake_build_type = decide_cmake_build_type(tool)
        cmake_build_types = [default_cmake_build_type, 'Release', 'RelWithDebInfo', 'MinSizeRel', 'Debug']
        for build_type in cmake_build_types:
            d = os.path.join(build_dir, build_type, 'bin')
            if os.path.isfile(os.path.join(tool.installation_path(), d, exe_suffix('clang'))):
                new_llvm_bin_dir = d
                break

        if new_llvm_bin_dir and os.path.exists(os.path.join(tool.installation_path(), new_llvm_bin_dir)):
            return new_llvm_bin_dir
        elif os.path.exists(os.path.join(tool.installation_path(), old_llvm_bin_dir)):
            return old_llvm_bin_dir
        return os.path.join(build_dir, default_cmake_build_type, 'bin')
    else:
        return os.path.join(build_dir, 'bin')


def build_env():
    if WINDOWS and 'Visual Studio' in CMAKE_GENERATOR:
        env = os.environ.copy()
        # MSBuild.exe has an internal mechanism to avoid N^2 oversubscription of threads in its two-tier build model, see
        # https://devblogs.microsoft.com/cppblog/improved-parallelism-in-msbuild/
        env['UseMultiToolTask'] = 'true'
        env['EnforceProcessCountAcrossBuilds'] = 'true'
        return env

    # By default, just inherit the parent env
    return None


def find_cmake():
    """Find path to cmake executable, as one of the activated tools, in PATH, or from installed tools."""
    def locate_cmake_from_tool(tool):
        tool_path = get_required_path([tool])
        tool_path = tool_path[-1]
        cmake_exe = 'cmake.exe' if WINDOWS else 'cmake'
        cmake_exe = os.path.join(tool_path, cmake_exe)
        if os.path.isfile(cmake_exe):
            return cmake_exe

    # 1. If user has activated a specific cmake tool, then use that tool to configure the build.
    for tool in reversed(tools):
        if tool.id == 'cmake' and tool.is_active():
            cmake_exe = locate_cmake_from_tool(tool)
            if cmake_exe:
                info(f'Found installed+activated CMake tool at "{cmake_exe}"')
                return cmake_exe

    # 2. If cmake already exists in PATH, then use that cmake to configure the build.
    cmake_exe = shutil.which('cmake')
    if cmake_exe:
        info(f'Found CMake from PATH at "{cmake_exe}"')
        return cmake_exe

    # 3. Finally, if user has installed a cmake tool, but has not activated that, then use
    # that tool. This enables a single-liner directive
    #   "emsdk install cmake-4.2.0-rc3-64bit llvm-git-main-64bit" to first install CMake, and
    # then use it to configure to build LLVM.
    for tool in reversed(tools):
        if tool.id == 'cmake' and tool.is_installed():
            cmake_exe = locate_cmake_from_tool(tool)
            if cmake_exe:
                info(f'Found installed CMake tool at "{cmake_exe}"')
                return cmake_exe

    exit_with_error('Unable to find "cmake" in PATH, or as installed/activated tool! Please install CMake first')


def make_build(build_root, build_type):
    debug_print(f'make_build(build_root={build_root}, build_type={build_type})')
    if CPU_CORES > 1:
        print(f'Performing a parallel build with {CPU_CORES} cores.')
    else:
        print('Performing a singlethreaded build.')

    make = [find_cmake(), '--build', '.', '--config', build_type]
    if 'Visual Studio' in CMAKE_GENERATOR:
        # Visual Studio historically has had a two-tier problem in its build system design. A single MSBuild.exe instance only governs
        # the build of a single project (.exe/.lib/.dll) in a solution. Passing the -j parameter above will only enable multiple MSBuild.exe
        # instances to be spawned to build multiple projects in parallel, but each MSBuild.exe is still singlethreaded.
        # To enable each MSBuild.exe instance to also compile several .cpp files in parallel inside a single project, pass the extra
        # MSBuild.exe specific "Multi-ToolTask" (MTT) setting /p:CL_MPCount. This enables each MSBuild.exe to parallelize builds wide.
        # This requires CMake 3.12 or newer.
        make += ['-j', str(CPU_CORES), '--', '/p:CL_MPCount=' + str(CPU_CORES)]
    else:
        # Pass -j to native make, CMake might not support -j option.
        make += ['--', '-j', str(CPU_CORES)]

    # Build
    print('Running build: ' + str(make))
    ret = subprocess.call(make, cwd=build_root, env=build_env())
    if ret != 0:
        errlog(f'Build failed with exit code {ret}!')
        errlog('Working directory: ' + build_root)
        return False

    return True


def write_file(filename, content):
    with open(filename, 'w', encoding='utf-8') as f:
        f.write(content)


def read_file(filename):
    with open(filename, encoding='utf-8') as f:
        return f.read()


def cmake_configure(generator, build_root, src_root, build_type, extra_cmake_args):
    debug_print(f'cmake_configure(generator={generator}, build_root={build_root}, '
                f'src_root={src_root}, build_type={build_type}, extra_cmake_args={extra_cmake_args})')
    # Configure
    if not os.path.isdir(build_root):
        # Create build output directory if it doesn't yet exist.
        os.mkdir(build_root)
    cmdline = [find_cmake(), '-DCMAKE_BUILD_TYPE=' + build_type, '-DPYTHON_EXECUTABLE=' + sys.executable]
    if generator:
        cmdline += ['-G', generator]
    # Target macOS 11.0 Big Sur at minimum, to support older Mac devices.
    # See https://en.wikipedia.org/wiki/MacOS#Hardware_compatibility for min-spec details.
    cmdline += ['-DCMAKE_OSX_DEPLOYMENT_TARGET=11.0']
    cmdline += [*extra_cmake_args, src_root]

    print(f'Running CMake: {cmdline}')

    # Specify the deployment target also as an env. var, since some Xcode versions
    # read this instead of the CMake field.
    os.environ['MACOSX_DEPLOYMENT_TARGET'] = '11.0'

    def quote_parens(x):
        if ' ' in x:
            return '"' + x.replace('"', '\\"') + '"'
        else:
            return x

    # Create a file 'recmake.bat/sh' in the build root that user can call to
    # manually recmake the build tree with the previous build params
    re_cmake_script = os.path.join(build_root, 'recmake.' + ('bat' if WINDOWS else 'sh'))
    write_file(re_cmake_script, ' '.join(map(quote_parens, cmdline)))
    try:
        subprocess.check_call(cmdline, cwd=build_root, env=build_env())
    except Exception as e:
        errlog('CMake invocation failed due to exception')
        errlog(f'Working directory: {build_root}')
        errlog(str(e))
        return False

    return True


def xcode_sdk_version():
    try:
        output = run_get_output(['xcrun', '--show-sdk-version'])
        return output.strip().split('.')
    except Exception:
        return subprocess.checkplatform.mac_ver()[0].split('.')


def cmake_target_platform(tool):
    # Source: https://cmake.org/cmake/help/latest/generator/Visual%20Studio%2017%202022.html#platform-selection
    if tool.arch:
        if tool.arch == 'arm64':
            return 'ARM64'
        elif tool.arch == 'x86_64':
            return 'x64'
        elif tool.arch == 'x86':
            return 'Win32'
    if ARCH == 'arm64':
        return 'ARM64'
    else:
        return 'x64' if tool.bitness == 64 else 'Win32'


def cmake_host_platform():
    # Source: https://cmake.org/cmake/help/latest/generator/Visual%20Studio%2017%202022.html#toolset-selection
    arch_to_cmake_host_platform = {
      'arm64': 'ARM64',
      'arm': 'ARM',
      'x86_64': 'x64',
      'x86': 'x86',
    }
    return arch_to_cmake_host_platform[ARCH]


def get_generator_and_config_args(tool):
    args = []
    cmake_generator = CMAKE_GENERATOR
    if 'Visual Studio 16' in CMAKE_GENERATOR or 'Visual Studio 17' in CMAKE_GENERATOR:  # VS2019 or VS2022
        # With Visual Studio 16 2019, CMake changed the way they specify target arch.
        # Instead of appending it into the CMake generator line, it is specified
        # with a -A arch parameter.
        args += ['-A', cmake_target_platform(tool)]
        args += ['-Thost=' + cmake_host_platform()]
    elif 'Visual Studio' in CMAKE_GENERATOR and tool.bitness == 64:
        cmake_generator += ' Win64'
        args += ['-Thost=x64']
    return (cmake_generator, args)


def cmake_configure_and_build(cmake_generator, build_root, cmakelists_dir, build_type, args):
    success = cmake_configure(cmake_generator, build_root, cmakelists_dir, build_type, args)
    if success:
        success = make_build(build_root, build_type)

    if not success and get_env_boolean('EMSDK_RETRY_CLEAN_BUILD'):
        # Delete the CMake build directory to force a full re-cmake + clean rebuild.
        shutil.rmtree(build_root)

        # And re-try configure + build again.
        success = cmake_configure(cmake_generator, build_root, cmakelists_dir, build_type, args)
        if success:
            success = make_build(build_root, build_type)

    return success


def build_llvm(tool):
    debug_print(f'build_llvm({tool})')
    llvm_root = tool.installation_path()
    llvm_src_root = os.path.join(llvm_root, 'src')
    success = git_clone_checkout_and_pull(tool.url, llvm_src_root, tool.git_branch)
    if not success:
        return False

    build_dir = llvm_build_dir(tool)
    build_root = os.path.join(llvm_root, build_dir)

    build_type = decide_cmake_build_type(tool)

    # Configure
    tests_arg = 'ON' if BUILD_FOR_TESTING else 'OFF'

    enable_assertions = ENABLE_LLVM_ASSERTIONS.lower() == 'on' or (ENABLE_LLVM_ASSERTIONS == 'auto' and build_type.lower() not in {'release', 'minsizerel'})

    if ARCH in {'x86', 'x86_64'}:
        targets_to_build = 'WebAssembly;X86'
    elif ARCH == 'arm':
        targets_to_build = 'WebAssembly;ARM'
    elif ARCH == 'arm64':
        targets_to_build = 'WebAssembly;AArch64'
    else:
        targets_to_build = 'WebAssembly'
    cmake_generator, args = get_generator_and_config_args(tool)
    args += ['-DLLVM_TARGETS_TO_BUILD=' + targets_to_build,
             '-DLLVM_INCLUDE_EXAMPLES=OFF',
             '-DLLVM_INCLUDE_TESTS=' + tests_arg,
             '-DCLANG_INCLUDE_TESTS=' + tests_arg,
             '-DLLVM_ENABLE_ASSERTIONS=' + ('ON' if enable_assertions else 'OFF'),
             # Disable optional LLVM dependencies, these can cause unwanted .so dependencies
             # that prevent distributing the generated compiler for end users.
             '-DLLVM_ENABLE_LIBXML2=OFF', '-DLLDB_ENABLE_LIBEDIT=OFF',
             '-DLLVM_ENABLE_LIBEDIT=OFF', '-DLLVM_ENABLE_LIBPFM=OFF']
    # LLVM build system bug: compiler-rt does not build on Windows. It insists on performing a CMake install step that writes to C:\Program Files. Attempting
    # to reroute that to build_root directory then fails on an error
    #  file INSTALL cannot find
    #  "C:/code/emsdk/llvm/git/build_master_vs2017_64/$(Configuration)/lib/clang/10.0.0/lib/windows/clang_rt.ubsan_standalone-x86_64.lib".
    # (there instead of $(Configuration), one would need ${CMAKE_BUILD_TYPE} ?)
    # It looks like compiler-rt is not compatible to build on Windows?
    args += ['-DLLVM_ENABLE_PROJECTS=clang;lld']
    # To enable widest possible chance of success for building, let the code
    # compile through with older toolchains that are about to be deprecated by
    # upstream LLVM.
    args += ['-DLLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN=ON']

    if os.getenv('LLVM_CMAKE_ARGS'):
        extra_args = os.environ['LLVM_CMAKE_ARGS'].split(',')
        print('Passing the following extra arguments to LLVM CMake configuration: ' + str(extra_args))
        args += extra_args

    cmakelists_dir = os.path.join(llvm_src_root, 'llvm')

    success = cmake_configure_and_build(cmake_generator, build_root, cmakelists_dir, build_type, args)

    return success


def build_ninja(tool):
    debug_print(f'build_ninja({tool})')
    root = os.path.normpath(tool.installation_path())
    src_root = os.path.join(root, 'src')
    success = git_clone_checkout_and_pull(tool.url, src_root, tool.git_branch)
    if not success:
        return False

    build_dir = llvm_build_dir(tool)
    build_root = os.path.join(root, build_dir)

    build_type = decide_cmake_build_type(tool)

    # Configure
    cmake_generator, args = get_generator_and_config_args(tool)

    cmakelists_dir = os.path.join(src_root)

    success = cmake_configure_and_build(cmake_generator, build_root, cmakelists_dir, build_type, args)

    if success:
        bin_dir = os.path.join(root, 'bin')
        mkdir_p(bin_dir)
        exe_paths = [os.path.join(build_root, 'Release', 'ninja'), os.path.join(build_root, 'ninja')]
        for e in exe_paths:
            for s in ['.exe', '']:
                ninja = e + s
                if os.path.isfile(ninja):
                    dst = os.path.join(bin_dir, 'ninja' + s)
                    shutil.copyfile(ninja, dst)
                    os.chmod(dst, os.stat(dst).st_mode | stat.S_IEXEC)

    return success


def build_ccache(tool):
    debug_print(f'build_ccache({tool})')
    root = os.path.normpath(tool.installation_path())
    src_root = os.path.join(root, 'src')
    success = git_clone_checkout_and_pull(tool.url, src_root, tool.git_branch)
    if not success:
        return False

    build_dir = llvm_build_dir(tool)
    build_root = os.path.join(root, build_dir)

    build_type = decide_cmake_build_type(tool)

    # Configure
    cmake_generator, args = get_generator_and_config_args(tool)
    args += ['-DZSTD_FROM_INTERNET=ON']

    cmakelists_dir = os.path.join(src_root)

    success = cmake_configure_and_build(cmake_generator, build_root, cmakelists_dir, build_type, args)

    if success:
        bin_dir = os.path.join(root, 'bin')
        mkdir_p(bin_dir)
        exe_paths = [os.path.join(build_root, 'Release', 'ccache'), os.path.join(build_root, 'ccache')]
        for e in exe_paths:
            for s in ['.exe', '']:
                ccache = e + s
                if os.path.isfile(ccache):
                    dst = os.path.join(bin_dir, 'ccache' + s)
                    shutil.copyfile(ccache, dst)
                    os.chmod(dst, os.stat(dst).st_mode | stat.S_IEXEC)

        cache_dir = os.path.join(root, 'cache')
        write_file(os.path.join(root, 'emcc_ccache.conf'), f'''\
    # Set maximum cache size to 10 GB:
    max_size = 10G
    cache_dir = {cache_dir}
    ''')
        mkdir_p(cache_dir)

    return success


def download_firefox(tool):
    debug_print(f'download_firefox({tool})')

    # Use mozdownload to acquire Firefox versions.
    try:
        from mozdownload import FactoryScraper
    except ImportError:
        # If mozdownload is not available, invoke pip to install it.
        subprocess.check_call([sys.executable, "-m", "pip", "install", "mozdownload"])
        from mozdownload import FactoryScraper

    if WINDOWS:
        extension = 'exe'
    elif MACOS:
        extension = 'dmg'
    else:
        # N.b. on Linux even when we ask .tar.xz, we might sometimes get .tar.bz2,
        # depending on what is available on Firefox servers for the particular
        # version. So prepare to handle both further down below.
        extension = 'tar.xz'

    platform = None
    if LINUX and 'arm' in ARCH:
        platform = 'linux-arm64'
    if WINDOWS and 'arm' in ARCH:
        platform = 'win64-aarch64'

    if tool.version == 'nightly':
        scraper = FactoryScraper('daily', extension=extension, locale='en-US', platform=platform)
    else:
        scraper = FactoryScraper('release', extension=extension, locale='en-US', platform=platform, version=tool.version)

    if tool.version == 'nightly':
        firefox_version = os.path.basename(scraper.filename).split(".en-US")[0]
    else:
        firefox_version = os.path.basename(scraper.filename).split("firefox-")[1].split(".en-US")[0]

    print('Target Firefox version: ' + firefox_version)
    if tool.version in {'latest', 'latest-esr', 'latest-beta', 'nightly'}:
        pretend_version_dir = os.path.normpath(tool.installation_path())
        orig_version = tool.version
        tool.version = firefox_version
        root = os.path.normpath(tool.installation_path())
        tool.version = orig_version
    else:
        pretend_version_dir = None
        root = os.path.normpath(tool.installation_path())

    def save_actual_version():
        """For moving installer packages, e.g. "nightly", "latest", "latest-esr",
        store a text file to specify the actual installation directory.
        """
        if os.path.isfile(firefox_exe) and pretend_version_dir:
            print(pretend_version_dir)
            os.makedirs(pretend_version_dir, exist_ok=True)
            write_file(os.path.join(pretend_version_dir, 'actual.txt'), os.path.relpath(root, EMSDK_PATH))

    # Check if already installed
    print('Firefox installation root directory: ' + root)
    exe_dir = os.path.join(root, 'Contents', 'MacOS') if MACOS else root
    firefox_exe = os.path.join(exe_dir, exe_suffix('firefox'))
    if os.path.isfile(firefox_exe):
        print(f'{firefox_exe} is already installed, skipping..')
        save_actual_version()
        return True

    print('Downloading Firefox from ' + scraper.url)
    filename = scraper.download()
    print('Finished downloading ' + filename)

    if not MACOS:
        os.makedirs(root, exist_ok=True)

    if extension == 'exe':
        # Uncompress the NSIS installer to 'install' Firefox
        run(['C:\\Program Files\\7-Zip\\7z.exe', 'x', '-y', filename, '-o' + root])

    if '.tar.' in filename:
        if filename.endswith('.tar.bz2'):
            tar_type = 'r:bz2'
        elif filename.endswith('.tar.xz'):
            tar_type = 'r:xz'
        else:
            raise Exception('Unknown archive type')

        with tarfile.open(filename, tar_type) as tar:
            tar.extractall(path=root)
        collapse_subdir = os.path.join(root, 'firefox')

    elif filename.endswith('.dmg'):
        mount_point = '/Volumes/Firefox Nightly' if tool.version == 'nightly' else '/Volumes/Firefox'
        app_name = 'Firefox Nightly.app' if tool.version == 'nightly' else 'Firefox.app'

        # If a previous mount point exists, detach it first
        if os.path.exists(mount_point):
            run(['hdiutil', 'detach', mount_point])

        # Abort if detaching was not successful
        if os.path.exists(mount_point):
            raise Exception(f'Previous mount of Firefox already exists at "{mount_point}", unable to proceed.')

        # Mount the archive
        run(['hdiutil', 'attach', filename])
        firefox_dir = os.path.join(mount_point, app_name)
        if not os.path.isdir(firefox_dir):
            raise Exception(f'Unable to find Firefox directory "{firefox_dir}" inside app image.')

        # And install by copying the files from the archive
        shutil.copytree(firefox_dir, root)
        run(['hdiutil', 'detach', mount_point])
        collapse_subdir = None

    elif filename.endswith('.exe'):
        # NSIS installer package has a core/ directory, remove it as redundant.
        collapse_subdir = os.path.join(root, 'core')

    # Remove a redundant subdirectory by moving installed files up one directory.
    if collapse_subdir and os.path.isdir(collapse_subdir):
        # Rename the parent subdirectory first, since we will be handling a nested `firefox/firefox/`
        collapse = collapse_subdir + '_temp_renamed'
        os.rename(collapse_subdir, collapse)

        # Move all files up by one directory
        for f in os.listdir(collapse):
            shutil.move(os.path.join(collapse, f), os.path.dirname(collapse))

        # The root directory should now be empty
        os.rmdir(collapse)

    # Original installer is now done.
    os.remove(filename)

    # Write a policy file that prevents Firefox from auto-updating itself.
    if MACOS:
        distribution_path = os.path.join(root, 'Contents', 'Resources', 'distribution')
    else:
        distribution_path = os.path.join(root, 'distribution')
    os.makedirs(distribution_path, exist_ok=True)
    write_file(os.path.join(distribution_path, 'policies.json'), '''\
  {
    "policies": {
      "AppAutoUpdate": false,
      "DisableAppUpdate": true
    }
  }''')

    if MACOS:
        # Disable a macOS feature where if the browser is terminated mid-execution, (e.g. by
        # CI aborting), then the next time the browser is launched, macOS might bring up a dialog
        # "The last time you opened Firefox, it unexpectedly quit while reopening windows.
        #  Do you want to try to reopen its windows again?"
        # that will block automated CI runs.
        # Disable this feature by changing the behavior of the program with macOS 'defaults'.
        run(['defaults', 'write', '-app', root, 'ApplePersistenceIgnoreState', 'YES'])
        run(['defaults', 'write', '-app', root, 'NSQuitAlwaysKeepsWindows', '-bool', 'false'])

    save_actual_version()

    # If we didn't get a Firefox executable, then installation failed.
    return os.path.isfile(firefox_exe)


def is_firefox_installed(tool):
    actual_file = os.path.join(tool.installation_dir(), 'actual.txt')
    if not os.path.isfile(actual_file):
        return False

    actual_installation_dir = sdk_path(read_file(actual_file))
    exe_dir = os.path.join(actual_installation_dir, 'Contents', 'MacOS') if MACOS else actual_installation_dir
    firefox_exe = os.path.join(exe_dir, exe_suffix('firefox'))
    return os.path.isfile(firefox_exe)


def find_latest_installed_tool(name):
    """Finds the newest installed version of a given tool"""
    for t in reversed(tools):
        if t.id == name and t.is_installed():
            return t


def get_node_env():
    node_tool = find_latest_installed_tool('node')
    if node_tool:
        node_path = node_tool.expand_vars(node_tool.activated_path)
    else:
        npm_fallback = shutil.which('npm')
        if not npm_fallback:
            errlog('Failed to find npm command')
            errlog('npm is required for Emscripten setup. Please install node.js first')
            return None, None
        node_path = os.path.dirname(npm_fallback)

    env = os.environ.copy()
    env["PATH"] = node_path + os.pathsep + env["PATH"]
    return env, node_path


def emscripten_npm_setup(directory):
    env, node_path = get_node_env()
    if not env:
        return False
    npm = os.path.join(node_path, 'npm' + ('.cmd' if WINDOWS else ''))
    print('Running post-install step: npm ci ...')
    try:
        subprocess.check_call([npm, 'ci', '--production'], cwd=directory, env=env)
    except subprocess.CalledProcessError as e:
        errlog(f'Error running {e.cmd}')
        return False

    print('Done running: npm ci')
    return True


def sdk_post_install():
    """Older versions of the sdk did not include the node_modules directory
    and require `npm ci` to be run post-install
    """
    emscripten_dir = os.path.join(EMSDK_PATH, 'upstream', 'emscripten')
    if os.path.exists(os.path.join(emscripten_dir, 'node_modules')):
        return True

    return emscripten_npm_setup(emscripten_dir)


def emscripten_install(tool):
    """Modern versions of emscripten require bootstrap.py to be run before they
    can be used from a git checkout. On older versions we just run `npm ci`
    """
    directory = tool.installation_path()
    if os.path.isfile(os.path.join(directory, 'bootstrap.py')):
        env = get_node_env()[0]
        if not env:
            return False
        try:
            subprocess.check_call([sys.executable, os.path.join(directory, 'bootstrap.py')],
                                  cwd=directory, stdin=subprocess.DEVNULL, env=env, text=True)
        except subprocess.CalledProcessError as e:
            errlog(f'Error running {e!s}')
            return False

        print('Done running: Emscripten bootstrap')
    else:
        return emscripten_npm_setup(directory)

    return True


# Binaryen build scripts:
def binaryen_build_root(tool):
    build_root = tool.installation_path().strip()
    if build_root.endswith(('/', '\\')):
        build_root = build_root[:-1]
    generator_prefix = cmake_generator_prefix()
    build_root = f'{build_root}{generator_prefix}_{tool.bitness}bit_binaryen'
    return build_root


def uninstall_binaryen(tool):
    debug_print(f'uninstall_binaryen({tool})')
    build_root = binaryen_build_root(tool)
    print(f"Deleting path '{build_root}'")
    remove_tree(build_root)


def is_binaryen_installed(tool):
    build_root = binaryen_build_root(tool)
    return os.path.exists(build_root)


def build_binaryen_tool(tool):
    debug_print(f'build_binaryen_tool({tool})')
    src_root = tool.installation_path()
    build_root = binaryen_build_root(tool)
    build_type = decide_cmake_build_type(tool)

    # Configure
    cmake_generator, args = get_generator_and_config_args(tool)
    args += ['-DENABLE_WERROR=0']  # -Werror is not useful for end users
    args += ['-DBUILD_TESTS=0']  # We don't want to build or run tests

    if 'Visual Studio' in CMAKE_GENERATOR:
        if BUILD_FOR_TESTING:
            args += ['-DRUN_STATIC_ANALYZER=1']

    success = cmake_configure_and_build(cmake_generator, build_root, src_root, build_type, args)

    if success:
        # Deploy scripts needed from source repository to build directory
        remove_tree(os.path.join(build_root, 'scripts'))
        shutil.copytree(os.path.join(src_root, 'scripts'), os.path.join(build_root, 'scripts'))
        remove_tree(os.path.join(build_root, 'src', 'js'))
        shutil.copytree(os.path.join(src_root, 'src', 'js'), os.path.join(build_root, 'src', 'js'))

    return success


def download_and_extract(archive, dest_dir, filename_prefix='', clobber=True):
    debug_print(f'download_and_extract(archive={archive}, dest_dir={dest_dir})')

    url = urljoin(emsdk_packages_url, archive)

    def try_download(url):
        return download_file(url, download_dir, filename_prefix)

    # Special hack for the wasm-binaries we transitioned from `.bzip2` to
    # `.xz`, but we can't tell from the version/url which one to use, so
    # try one and then fall back to the other.
    success = False
    if 'wasm-binaries' in archive and os.path.splitext(archive)[1] == '.xz':
        success = try_download(url)
        if not success:
            alt_url = url.replace('.tar.xz', '.tbz2')
            success = try_download(alt_url)
            if success:
                url = alt_url

    if not success:
        success = try_download(url)

    if not success:
        return False

    # Remove the old directory, since we have some SDKs that install into the
    # same directory.  If we didn't do this contents of the previous install
    # could remain.
    if clobber:
        remove_tree(dest_dir)

    download_target = get_download_target(url, download_dir, filename_prefix)
    if archive.endswith('.zip'):
        return unzip(download_target, dest_dir)
    else:
        return untargz(download_target, dest_dir)


def to_native_path(p):
    if (WINDOWS and not MSYS) and not os_override:
        return to_unix_path(p).replace('/', '\\')
    else:
        return to_unix_path(p)


def get_required_path(active_tools):
    """Finds and returns a list of the directories that need to be added to PATH for
    the given set of tools.
    """
    path_add = [to_native_path(EMSDK_PATH)]
    for tool in active_tools:
        if tool.activated_path:
            path = to_native_path(tool.expand_vars(tool.activated_path))
            # If the tool has an activated_path_skip attribute then we don't add
            # the tools path to the users path if a program by that name is found
            # in the existing PATH.  This allows us to, for example, add our version
            # node to the users PATH if, and only if, they don't already have a
            # another version of node in their PATH.
            if tool.activated_path_skip:
                current_path = shutil.which(tool.activated_path_skip)
                # We found an executable by this name in the current PATH, but we
                # ignore our own version for this purpose.
                if current_path and os.path.dirname(current_path) != path:
                    continue
            path_add.append(path)
    return path_add


# Returns the absolute path to the file '.emscripten' for the current user on
# this system.
EM_CONFIG_PATH = os.path.join(EMSDK_PATH, ".emscripten")
EM_CONFIG_DICT = {}


def parse_key_value(line):
    if not line:
        return ('', '')
    eq = line.find('=')
    if eq != -1:
        key = line[0:eq].strip()
        value = line[eq + 1:].strip()
        return (key, value)
    else:
        return (key, '')


def load_em_config():
    EM_CONFIG_DICT.clear()
    lines = []
    try:
        lines = read_file(EM_CONFIG_PATH).splitlines()
    except Exception:
        pass
    for line in lines:
        try:
            key, value = parse_key_value(line)
            if value:
                EM_CONFIG_DICT[key] = value
        except Exception:
            pass


def find_emscripten_root(active_tools):
    """Find the currently active emscripten root.

    If there is more than one tool that defines EMSCRIPTEN_ROOT (this
    should not happen under normal circumstances), assume the last one takes
    precedence.
    """
    root = None
    for tool in active_tools:
        config = tool.activated_config()
        if 'EMSCRIPTEN_ROOT' in config:
            root = config['EMSCRIPTEN_ROOT']
    return root


def fetch_nightly_node_versions():
    url = "https://nodejs.org/download/nightly/"
    with urlopen(url) as response:
        html = response.read().decode("utf-8")

    # Regex to capture href values like v7.0.0-nightly2016080175c6d9dd95/
    pattern = re.compile(r'<a href="(v[0-9]+\.[0-9]+\.[0-9]+-nightly[0-9a-f]+)/">')
    matches = pattern.findall(html)
    return matches


def dir_installed_nightly_node_versions():
    path = os.path.abspath('node')
    try:
        return [name for name in os.listdir(path) if os.path.isdir(os.path.join(path, name)) and name.startswith("nightly-")]
    except Exception:
        return []


def extract_newest_node_nightly_version(versions):
    def parse(v):
        # example: v7.0.0-nightly2016080175c6d9dd95
        m = re.search(r'v(\d+)\.(\d+)\.(\d+)-nightly(\d{8})', v)
        if m:
            major, minor, patch, nightly = m.groups()
            return [int(major), int(minor), int(patch), int(nightly)]
        else:
            return []

    try:
        return max(versions, key=parse)
    except Exception:
        return None


def download_node_nightly(tool):
    nightly_versions = fetch_nightly_node_versions()
    latest_nightly = extract_newest_node_nightly_version(nightly_versions)
    print(f'Latest Node.js Nightly download available is "{latest_nightly}"')

    output_dir = os.path.abspath('node/nightly-' + latest_nightly)
    # Node.js zip structure quirk: Linux and macOS archives have a /bin,
    # Windows does not. Unify the file structures.
    if WINDOWS:
        output_dir += '/bin'

    if os.path.isdir(output_dir):
        return True

    url = tool.url.replace('%version%', latest_nightly)
    if WINDOWS:
        os_ = 'win'
    elif LINUX:
        os_ = 'linux'
    elif MACOS:
        os_ = 'darwin'
    else:
        os_ = ''
    if platform.machine().lower() in {'x86_64', 'amd64'}:
        arch = 'x64'
    elif platform.machine().lower() in {'arm64', 'aarch64'}:
        arch = 'arm64'
    if WINDOWS:
        zip_suffix = 'zip'
    else:
        zip_suffix = 'tar.gz'
    url = url.replace('%os%', os_)
    url = url.replace('%arch%', arch)
    url = url.replace('%zip_suffix%', zip_suffix)
    download_and_extract(url, output_dir)
    write_file(tool.get_version_file_path(), 'node-nightly-64bit')
    return True


def get_emsdk_shell_env_configs():
    """returns a tuple (string,string) of config files paths that need to used
    to activate emsdk env depending on $SHELL, defaults to bash.
    """
    default_emsdk_env = sdk_path('emsdk_env.sh')
    default_shell_config_file = '$HOME/.bash_profile'
    shell = os.getenv('SHELL', '')
    if 'zsh' in shell:
        return (default_emsdk_env, '$HOME/.zprofile')
    elif 'csh' in shell:
        return (sdk_path('emsdk_env.csh'), '$HOME/.cshrc')
    elif 'fish' in shell:
        return (sdk_path('emsdk_env.fish'), '$HOME/.config/fish/config.fish')
    else:
        return (default_emsdk_env, default_shell_config_file)


def generate_em_config(active_tools, permanently_activate, system):
    emroot = find_emscripten_root(active_tools)
    version = None
    if emroot and os.path.exists(os.path.join(emroot, 'emscripten-version.txt')):
        version = parse_emscripten_version(emroot)

    supports_cfgdir = version and version >= [6, 0, 4]

    cfg = ''
    if not supports_cfgdir:
        cfg += 'import os\n'
        cfg += "emsdk_path = os.path.dirname(os.getenv('EM_CONFIG')).replace('\\\\', '/')\n"

    # Different tools may provide the same activated configs; the latest to be
    # activated is the relevant one.
    activated_config = {}
    for tool in active_tools:
        activated_config.update(tool.activated_config())

    if 'NODE_JS' not in activated_config:
        node_fallback = shutil.which('nodejs')
        if not node_fallback:
            node_fallback = 'node'
        activated_config['NODE_JS'] = node_fallback

    for name, value in activated_config.items():
        if value.startswith('['):
            cfg += f'{name} = {value}\n'
        else:
            cfg += f"{name} = '{value}'\n"

    if version:
        # Older emscripten versions of emscripten depend on certain config
        # keys that are no longer used.
        # See https://github.com/emscripten-core/emscripten/pull/9469
        if version < [1, 38, 46]:
            cfg += 'COMPILER_ENGINE = NODE_JS\n'
        # See https://github.com/emscripten-core/emscripten/pull/9542
        if version < [1, 38, 48]:
            cfg += 'JS_ENGINES = [NODE_JS]\n'

    if supports_cfgdir:
        cfg = cfg.replace(EMSDK_PATH, '$CFGDIR')
    else:
        cfg = cfg.replace("'" + EMSDK_PATH, "emsdk_path + '")

    if os.path.exists(EM_CONFIG_PATH):
        backup_path = EM_CONFIG_PATH + ".old"
        move_with_overwrite(EM_CONFIG_PATH, backup_path)

    write_file(EM_CONFIG_PATH, cfg)

    # Clear old emscripten content.
    rmfile(os.path.join(EMSDK_PATH, ".emscripten_sanity"))

    path_add = get_required_path(active_tools)

    # Give some recommended next step, depending on the platform
    if WINDOWS:
        if not permanently_activate and not system:
            print('Next steps:')
            print('- Consider running `emsdk activate` with --permanent or --system')
            print('  to have emsdk settings available on startup.')
    else:
        print('Next steps:')
        print('- To conveniently access emsdk tools from the command line,')
        print('  consider adding the following directories to your PATH:')
        for p in path_add:
            print('    ' + p)
        print('- This can be done for the current shell by running:')
        emsdk_env, shell_config_file = get_emsdk_shell_env_configs()
        print(f'    source "{emsdk_env}"')
        print('- Configure emsdk in your shell startup scripts by running:')
        print(f'    echo \'source "{emsdk_env}"\' >> {shell_config_file}')


class Tool:
    os = None
    bitness = None
    append_bitness = True
    is_old = False
    version = None
    activated_path = None
    cmake_build_type = None
    install_path = None
    activated_path_skip = False
    activated_cfg = None
    activated_env = None
    arch = None
    custom_is_installed_script = None
    custom_install_script = None
    custom_uninstall_script = None
    emscripten_releases_hash = None
    git_branch = None
    url = None

    def __init__(self, data):
        self.deps = []

        # Convert the dictionary representation of the tool in 'data' to members of
        # this class. Base attributes are assigned first, then host OS-matching suffixed
        # attributes (e.g. url_windows, activated_path_windows) are applied on top as overrides.
        # Foreign OS keys are ignored.
        os_overrides = {}
        all_os_names = {'windows', 'macos', 'linux'}

        for key, value in data.items():
            if '_' in key:
                prefix, suffix = key.rsplit('_', 1)
                if suffix in all_os_names:
                    if suffix == os_name():
                        os_overrides[prefix] = value
                    continue
            setattr(self, key, value)

        for prefix, value in os_overrides.items():
            setattr(self, prefix, value)

        # Cache the name ID of this Tool (these are read very often)
        self.name = self.id
        if self.version:
            self.name += f'-{self.version}'
        if self.bitness:
            self.name += f'-{self.bitness}bit'

    def __str__(self):
        return self.name

    def expand_vars(self, str):
        if '%installation_dir%' in str:
            str = str.replace('%installation_dir%', sdk_path(self.installation_dir()))
        if '%macos_app_bundle_prefix%' in str:
            str = str.replace('%macos_app_bundle_prefix%', 'Contents/MacOS/' if MACOS else '')
        if '%actual_installation_dir%' in str:
            actual_file = os.path.join(self.installation_dir(), 'actual.txt')
            if os.path.isfile(actual_file):
                str = str.replace('%actual_installation_dir%', sdk_path(read_file(actual_file)))
            else:
                str = str.replace('%actual_installation_dir%', '__NOT_INSTALLED__')
        if '%generator_prefix%' in str:
            str = str.replace('%generator_prefix%', cmake_generator_prefix())
        str = str.replace('%.exe%', '.exe' if WINDOWS else '')
        if '%llvm_build_bin_dir%' in str:
            str = str.replace('%llvm_build_bin_dir%', llvm_build_bin_dir(self))
        if '%latest_downloaded_node_nightly_dir%' in str:
            installed_node_nightlys = dir_installed_nightly_node_versions()
            latest_node_nightly = extract_newest_node_nightly_version(installed_node_nightlys)
            if latest_node_nightly:
                str = str.replace('%latest_downloaded_node_nightly_dir%', latest_node_nightly)

        return str

    def needs_compilation(self):
        """Return true if this tool requires building from source, and false if this is a precompiled tool."""
        if self.cmake_build_type:
            return True

        return any(dep.needs_compilation() for dep in self.dependencies())

    def installation_path(self):
        """Specifies the target path where this tool will be installed to. This could
        either be a directory or a filename (e.g. in case of node.js)
        """
        if self.install_path:
            pth = self.expand_vars(self.install_path)
            return sdk_path(pth)
        p = self.version
        if self.bitness and self.append_bitness:
            p += f'_{self.bitness}bit'
        return sdk_path(os.path.join(self.id, p))

    def installation_dir(self):
        """Specifies the target directory this tool will be installed to."""
        dir = self.installation_path()
        if path_points_to_directory(dir):
            return dir
        else:
            return os.path.dirname(dir)

    def activated_config(self):
        """Returns the configuration item that needs to be added to .emscripten to make
        this Tool active for the current user.
        """
        if not self.activated_cfg:
            return {}

        config = {}
        expanded = to_unix_path(self.expand_vars(self.activated_cfg))
        for specific_cfg in expanded.split(';'):
            name, value = specific_cfg.split('=')
            config[name] = value.strip("'")
        return config

    def activated_environment(self):
        if not self.activated_env:
            return []

        return self.expand_vars(self.activated_env).split(';')

    def compatible_with_this_arch(self):
        return self.arch == ARCH or not self.arch

    def compatible_with_this_os(self):
        if not self.compatible_with_this_arch():
            return False

        if self.os:
            assert self.os in {'linux', 'windows', 'macos'}
            return self.os == os_name()

        # Tools without an explicit 'os' are compatible with the current
        # OS if they have URL for the current OS *or* a set of dependencies
        # for the current OS.
        return self.url is not None or bool(self.deps)

    def get_version_file_path(self):
        """the "version file" is a file inside install dirs that indicates the
        version installed there. this helps disambiguate when there is more than
        one version that may be installed to the same directory (which is used
        to avoid accumulating builds over time in some cases, with new builds
        overwriting the old)
        """
        return os.path.join(self.installation_path(), '.emsdk_version')

    def is_installed_version(self):
        version_file_path = self.get_version_file_path()
        if os.path.isfile(version_file_path):
            return read_file(version_file_path).strip() == self.name
        return False

    def update_installed_version(self):
        write_file(self.get_version_file_path(), self.name + '\n')

    def is_installed(self, skip_version_check=False):
        # If this tool/sdk depends on other tools, require that all dependencies are
        # installed for this tool to count as being installed.
        for dep in self.dependencies():
            if not dep.is_installed():
                return False

        if self.url is None:
            debug_print(f'{self} has no files to download, so is installed by default.')
            return True

        content_exists = is_nonempty_directory(self.installation_path())
        debug_print(f'{self} installation path is {self.installation_path()}, exists: {content_exists}.')

        # For e.g. fastcomp clang from git repo, the activated PATH is the
        # directory where the compiler is built to, and installation_path is
        # the directory where the source tree exists. To distinguish between
        # multiple packages sharing the same source (clang-main-32bit,
        # clang-main-64bit, clang-main-32bit and clang-main-64bit each
        # share the same git repo), require that in addition to the installation
        # directory, each item in the activated PATH must exist.
        if self.activated_path and not os.path.exists(self.expand_vars(self.activated_path)):
            content_exists = False

        if self.custom_is_installed_script:
            if self.custom_is_installed_script == 'is_binaryen_installed':
                return is_binaryen_installed(self)
            elif self.custom_is_installed_script == 'is_firefox_installed':
                return is_firefox_installed(self)
            else:
                raise Exception(f'Unknown custom_is_installed_script: "{self.custom_is_installed_script}"')

        return content_exists and (skip_version_check or self.is_installed_version())

    def is_active(self):
        if not self.is_installed():
            return False

        # All dependencies of this tool must be active as well.
        deps = self.dependencies()
        for tool in deps:
            if not tool.is_active():
                return False

        activated_cfg = self.activated_config()
        if not activated_cfg:
            return len(deps) > 0

        for key, value in activated_cfg.items():
            if key not in EM_CONFIG_DICT:
                debug_print(f'{self} is not active, because key="{key}" does not exist in .emscripten')
                return False

            # all paths are stored dynamically relative to the emsdk root, so
            # normalize those first.
            config_value = EM_CONFIG_DICT[key].replace("emsdk_path + '", "'" + EMSDK_PATH).replace("$CFGDIR", EMSDK_PATH)
            config_value = config_value.strip("'")
            if config_value != value:
                debug_print(f'{self} is not active, because key="{key}" has value "{config_value}" but should have value "{value}"')
                return False
        return True

    def is_env_active(self):
        """Returns true if the system environment variables requires by this tool are currently active."""
        envs = self.activated_environment()
        for env in envs:
            key, value = parse_key_value(env)
            if key not in os.environ or to_unix_path(os.environ[key]) != to_unix_path(value):
                debug_print(f'{self} is not active, because environment variable key="{key}" has value "{os.getenv(key)}" but should have value "{value}"')
                return False

        if self.activated_path:
            path = to_unix_path(self.expand_vars(self.activated_path))
            for p in path:
                path_items = os.environ['PATH'].replace('\\', '/').split(ENVPATH_SEPARATOR)
                if not normalized_contains(path_items, p):
                    debug_print(f'{self} is not active, because environment variable PATH item "{p}" is not present (PATH={os.environ["PATH"]})')
                    return False
        return True

    def can_be_installed(self):
        """If this tool can be installed on this system, this function returns True.
        Otherwise, this function returns a string that describes the reason why this
        tool is not available.
        """
        if self.bitness == 64 and not is_os_64bit():
            return "this tool is only provided for 64-bit OSes"
        return True

    def install(self):
        """Returns True if the Tool was installed of False if was skipped due to
        already being installed.
        """
        if self.can_be_installed() is not True:
            exit_with_error(f"The tool '{self}' is not available due to the reason: {self.can_be_installed()}")

        if self.id == 'sdk':
            return self.install_sdk()
        else:
            return self.install_tool()

    def install_sdk(self):
        """Returns True if any SDK component was installed of False all componented
        were already installed.
        """
        print(f"Installing SDK '{self}'..")
        installed = False

        for dep in self.dependencies():
            installed |= dep.install()

        if not installed:
            print(f"All SDK components already installed: '{self}'.")
            return False

        if self.custom_install_script == 'sdk_post_install':
            if not sdk_post_install():
                exit_with_error('post-install step failed: sdk_post_install')

        print(f"Done installing SDK '{self}'.")
        return True

    def install_tool(self):
        """Returns True if the SDK was installed of False if was skipped due to
        already being installed.
        """
        # Avoid doing a redundant reinstall of the tool, if it has already been installed.
        # However all tools that are sourced directly from git branches do need to be
        # installed every time when requested, since the install step is then used to git
        # pull the tool to a newer version.
        if self.is_installed() and not self.git_branch:
            print(f"Skipped installing {self.name}, already installed.")
            return False

        print(f"Installing tool '{self}'..")

        custom_install_scripts = {
          'build_llvm': build_llvm,
          'build_ninja': build_ninja,
          'build_ccache': build_ccache,
          'download_node_nightly': download_node_nightly,
          'download_firefox': download_firefox,
        }
        if self.custom_install_script in custom_install_scripts:
            success = custom_install_scripts[self.custom_install_script](self)
        elif self.git_branch:
            success = git_clone_checkout_and_pull(self.url, self.installation_path(), self.git_branch, getattr(self, 'remote_name', 'origin'))
        elif self.url.endswith(ARCHIVE_SUFFIXES):
            success = download_and_extract(self.url, self.installation_path(),
                                           filename_prefix=getattr(self, 'download_prefix', ''))
        else:
            assert False, 'unhandled url type: ' + self.url

        if not success:
            exit_with_error("installation failed!")

        if self.custom_install_script:
            if self.custom_install_script == 'emscripten_install':
                success = emscripten_install(self)
            elif self.custom_install_script in {'build_llvm', 'build_ninja', 'build_ccache', 'download_node_nightly', 'download_firefox'}:
                # 'build_llvm' is a special one that does the download on its
                # own, others do the download manually.
                pass
            elif self.custom_install_script == 'build_binaryen':
                success = build_binaryen_tool(self)
            else:
                raise Exception(f'Unknown custom_install_script: "{self.custom_install_script}"')

        if not success:
            exit_with_error("installation failed!")

        # Install an emscripten-version.txt file if told to, and if there is one.
        # (If this is not an actual release, but some other build, then we do not
        # write anything.)
        if self.emscripten_releases_hash:
            emscripten_version_file_path = os.path.join(to_native_path(self.expand_vars(self.activated_path)), 'emscripten-version.txt')
            version = get_emscripten_release_version(self.emscripten_releases_hash)
            if version:
                write_file(emscripten_version_file_path, f'"{version}"\n')

        print(f"Done installing tool '{self}'.")

        # Sanity check that the installation succeeded, and if so, remove unneeded
        # leftover installation files.
        if not self.is_installed(skip_version_check=True):
            exit_with_error(f"installation of '{self}' failed, but no error was detected. "
                            "Either something went wrong with the installation, or this may indicate an internal emsdk error.")

        self.cleanup_temp_install_files()
        self.update_installed_version()
        return True

    def cleanup_temp_install_files(self):
        if KEEP_DOWNLOADS:
            return
        if self.url.endswith(ARCHIVE_SUFFIXES):
            download_target = get_download_target(self.url, download_dir, getattr(self, 'download_prefix', ''))
            debug_print(f"Deleting temporary download: {download_target}")
            rmfile(download_target)

    def uninstall(self):
        if not self.is_installed():
            print(f"Tool '{self}' was not installed. No need to uninstall.")
            return
        print(f"Uninstalling tool '{self}'..")
        if self.custom_uninstall_script:
            if self.custom_uninstall_script == 'uninstall_binaryen':
                uninstall_binaryen(self)
            else:
                raise Exception(f'Unknown custom_uninstall_script directive "{self.custom_uninstall_script}"!')
        print(f"Deleting path '{self.installation_path()}'")
        remove_tree(self.installation_path())
        print(f"Done uninstalling '{self}'.")

    def dependencies(self):
        deps = []

        for dep in self.deps:
            tool = find_tool(dep)
            assert tool, f"dependency '{dep}' of '{self}' not found"
            deps += [tool]
        return deps

    def recursive_dependencies(self):
        deps = []
        for dep in self.deps:
            tool = find_tool(dep)
            assert tool, f"dependency '{dep}' of '{self}' not found"
            deps += [tool]
            deps += tool.recursive_dependencies()
        return deps


# A global registry of all known Emscripten SDK tools available in the SDK manifest.
tools = []
tools_map = {}


def add_tool(tool):
    tool.is_sdk = False
    existing = find_tool(str(tool))
    if existing:
        raise Exception(f'Duplicate tool {tool}! Existing:\n{vars(existing)}, New:\n{vars(tool)}')
    tools.append(tool)
    tools_map[str(tool)] = tool


# A global registry of all known SDK toolsets.
sdks = []
sdks_map = {}


def add_sdk(sdk):
    sdk.is_sdk = True
    existing = find_sdk(str(sdk))
    if existing:
        raise Exception(f'Duplicate sdk {sdk}! Existing:\n{vars(existing)}, New:\n{vars(sdk)}')
    sdks.append(sdk)
    sdks_map[str(sdk)] = sdk


# N.B. In both tools and sdks list above, we take the convention that the newest
# items are at the back of the list (ascending chronological order)

def find_tool(name):
    return tools_map.get(name)


def find_sdk(name):
    return sdks_map.get(name)


def is_os_64bit():
    return ARCH.endswith('64')


def find_latest_version():
    return resolve_sdk_aliases('latest')


def find_latest_hash():
    version = find_latest_version()
    releases_info = load_releases_info()
    return releases_info['releases'][version]


def resolve_sdk_aliases(name, verbose=False):
    releases_info = load_releases_info()
    while name in releases_info['aliases']:
        if verbose:
            print(f"Resolving SDK alias '{name}' to '{releases_info['aliases'][name]}'")
        name = releases_info['aliases'][name]
    return name


def find_latest_sdk():
    return f'sdk-releases-{find_latest_hash()}-64bit'


def find_tot_sdk():
    debug_print('Fetching emscripten-releases repository...')
    global extra_release_tag
    extra_release_tag = get_emscripten_releases_tot()
    return f'sdk-releases-{extra_release_tag}-64bit'


def parse_emscripten_version(emscripten_root):
    version_file = os.path.join(emscripten_root, 'emscripten-version.txt')
    version = read_file(version_file).strip()
    version = version.strip('"')
    suffix = None
    if '-' in version:
        version, suffix = version.split('-')
    version = [int(v) for v in version.split('.')]
    if suffix == 'git':
        # Treat 1.2.3-git as 1.2.2 since it doesn't contain all the changes
        # present in the final 1.2.3 release.
        version[-1] -= 1
    return version


def get_emscripten_release_version(emscripten_releases_hash):
    """Given a git hash in emscripten-releases, find the emscripten
    version for it. There may not be one if this is not the hash of
    a release, in which case we return None.
    """
    releases_info = load_releases_info()
    for key, value in dict(releases_info['releases']).items():
        if value == emscripten_releases_hash:
            return key.split('-')[0]
    return None


def get_emscripten_releases_tot():
    """Get the tip-of-tree build identifier."""
    success = git_clone_checkout_and_pull(emscripten_releases_repo, sdk_path('releases'), 'main')
    if not success:
        exit_with_error('error checking out emscripten-releases repo')
    recent_releases = git_recent_commits(sdk_path('releases'))
    # The recent releases are the latest hashes in the git repo. There
    # may not be a build for the most recent ones yet; find the last
    # that has uploaded binaries for all platforms.
    all_platforms = [
      ('linux', '', 'tar.xz'),
      ('linux', '-arm64', 'tar.xz'),
      ('mac', '', 'tar.xz'),
      ('mac', '-arm64', 'tar.xz'),
      ('win', '', 'zip'),
    ]

    def check_binary(release, os_name, arch, ext):
        url = emscripten_releases_download_url_template % (os_name, release, arch, ext)
        try:
            urlopen(url)
            return True
        except Exception:
            return False

    for release in recent_releases:
        if all(check_binary(release, os_name, arch, ext) for os_name, arch, ext in all_platforms):
            return release

    # No recent release has binaries for all platforms
    exit_with_error('failed to find build of any recent emsdk revision')


def get_release_hash(arg, releases_info):
    return releases_info.get(arg, None) or releases_info.get(f'sdk-{arg}-64bit')


def version_key(ver):
    return tuple(map(int, re.split('[._-]', ver)[:3]))


def is_emsdk_sourced_from_github():
    return os.path.exists(os.path.join(EMSDK_PATH, '.git'))


def update_emsdk():
    if is_emsdk_sourced_from_github():
        errlog('You seem to have bootstrapped Emscripten SDK by cloning from GitHub. '
               'In this case, use "git pull" instead of "emsdk update" to update emsdk. '
               '(Not doing that automatically in case you have local changes)')
        sys.exit(1)
    if not download_and_extract(emsdk_zip_download_url, EMSDK_PATH, clobber=False):
        sys.exit(1)


def load_legacy_emscripten_tags():
    """Lists all legacy (pre-emscripten-releases) tagged versions directly in the Git
    repositories. These we can pull and compile from source.
    """
    return read_file(sdk_path('legacy-emscripten-tags.txt')).splitlines()


def load_legacy_binaryen_tags():
    return read_file(sdk_path('legacy-binaryen-tags.txt')).splitlines()


def remove_prefix(s, prefix):
    if s.startswith(prefix):
        return s[len(prefix):]
    else:
        return s


def remove_suffix(s, suffix):
    if s.endswith(suffix):
        return s[:len(s) - len(suffix)]
    else:
        return s


def load_file_index_list(filename):
    """filename should be one of: 'llvm-precompiled-tags-32bit.txt', 'llvm-precompiled-tags-64bit.txt'"""
    items = read_file(sdk_path(filename)).splitlines()
    items = [remove_suffix(remove_suffix(remove_prefix(x, 'emscripten-llvm-e'), '.tar.gz'), '.zip').strip() for x in items]
    items = [x for x in items if 'latest' not in x and len(x) > 0]

    # Sort versions from oldest to newest (the default sort would be
    # lexicographic, i.e. '1.37.1 < 1.37.10 < 1.37.2')
    return sorted(items, key=version_key)


def load_releases_info():
    """Load the json info for emscripten-releases."""
    if not hasattr(load_releases_info, 'cached_info'):
        try:
            text = read_file(sdk_path('emscripten-releases-tags.json'))
            load_releases_info.cached_info = json.loads(text)
        except Exception as e:
            print('Error parsing emscripten-releases-tags.json!')
            exit_with_error(str(e))

    return load_releases_info.cached_info


def get_installed_sdk_version():
    version_file = sdk_path(os.path.join('upstream', '.emsdk_version'))
    if not os.path.exists(version_file):
        return None
    version = read_file(version_file)
    return version.split('-')[1]


def load_releases_tags():
    """Get a list of tags for emscripten-releases."""
    tags = []
    info = load_releases_info()

    for _version, sha in sorted(info['releases'].items(), key=lambda x: version_key(x[0])):
        tags.append(sha)

    if extra_release_tag:
        tags.append(extra_release_tag)

    # Explicitly add the currently installed SDK version.  This could be a custom
    # version (installed explicitly) so it might not be part of the main list
    # loaded above.
    installed = get_installed_sdk_version()
    if installed and installed not in tags:
        tags.append(installed)

    return tags


def load_releases_versions():
    info = load_releases_info()
    versions = list(info['releases'].keys())
    return versions


def load_sdk_manifest():
    try:
        manifest = json.loads(read_file(sdk_path('emsdk_manifest.json')))
    except Exception:
        errlog('Error parsing emsdk_manifest.json!')
        raise

    emscripten_tags = load_legacy_emscripten_tags()
    llvm_precompiled_tags_32bit = []
    llvm_precompiled_tags_64bit = load_file_index_list('llvm-tags-64bit.txt')
    llvm_precompiled_tags = llvm_precompiled_tags_32bit + llvm_precompiled_tags_64bit
    binaryen_tags = load_legacy_binaryen_tags()
    releases_tags = load_releases_tags()

    def dependencies_exist(sdk):
        for dep in sdk.deps:
            tool = find_tool(dep)
            if not tool:
                debug_print('missing dependency: ' + dep)
                return False
        return True

    def cmp_version(ver, cmp_operand, reference):
        if cmp_operand == '<=':
            return version_key(ver) <= version_key(reference)
        if cmp_operand == '<':
            return version_key(ver) < version_key(reference)
        if cmp_operand == '>=':
            return version_key(ver) >= version_key(reference)
        if cmp_operand == '>':
            return version_key(ver) > version_key(reference)
        if cmp_operand == '==':
            return version_key(ver) == version_key(reference)
        if cmp_operand == '!=':
            return version_key(ver) != version_key(reference)
        raise Exception(f'Invalid cmp_operand "{cmp_operand}"!')

    def passes_filters(param, ver, filters):
        for v in filters:
            if v[0] == param and not cmp_version(ver, v[1], v[2]):
                return False
        return True

    def expand_category_param(param, category_list, t, is_sdk):
        """A 'category parameter' is a %foo%-encoded identifier that specifies
        a class of tools instead of just one tool, e.g. %tag%
        """
        for i, ver in enumerate(category_list):
            if not ver.strip():
                continue
            t2 = copy.copy(t)
            found_param = False
            for p, v in vars(t2).items():
                if isinstance(v, str) and param in v:
                    t2.__dict__[p] = v.replace(param, ver)
                    found_param = True
            if not found_param:
                continue
            t2.is_old = i < len(category_list) - 2
            t2.deps = [x.replace(param, ver) for x in t2.deps]

            if is_sdk:
                if dependencies_exist(t2):
                    if not find_sdk(t2.name):
                        add_sdk(t2)
                    else:
                        debug_print(f'SDK {t2} already existed in manifest, not adding twice')
            else:
                if not find_tool(t2.name):
                    add_tool(t2)
                else:
                    debug_print(f'Tool {t2} already existed in manifest, not adding twice')

    for tool in manifest['tools']:
        t = Tool(tool)
        if t.compatible_with_this_os():
            # Expand the metapackages that refer to tags
            if '%tag%' in t.version:
                expand_category_param('%tag%', emscripten_tags, t, is_sdk=False)
            elif '%precompiled_tag%' in t.version:
                expand_category_param('%precompiled_tag%', llvm_precompiled_tags, t, is_sdk=False)
            elif '%precompiled_tag32%' in t.version:
                expand_category_param('%precompiled_tag32%', llvm_precompiled_tags_32bit, t, is_sdk=False)
            elif '%precompiled_tag64%' in t.version:
                expand_category_param('%precompiled_tag64%', llvm_precompiled_tags_64bit, t, is_sdk=False)
            elif '%binaryen_tag%' in t.version:
                expand_category_param('%binaryen_tag%', binaryen_tags, t, is_sdk=False)
            elif '%releases-tag%' in t.version:
                expand_category_param('%releases-tag%', releases_tags, t, is_sdk=False)
            else:
                add_tool(t)

    for sdk_str in manifest['sdks']:
        sdk_str['id'] = 'sdk'
        sdk = Tool(sdk_str)
        if sdk.compatible_with_this_os():
            if not hasattr(sdk, 'is_old'):
                sdk.is_old = False

            if '%tag%' in sdk.version:
                expand_category_param('%tag%', emscripten_tags, sdk, is_sdk=True)
            elif '%precompiled_tag%' in sdk.version:
                expand_category_param('%precompiled_tag%', llvm_precompiled_tags, sdk, is_sdk=True)
            elif '%precompiled_tag32%' in sdk.version:
                expand_category_param('%precompiled_tag32%', llvm_precompiled_tags_32bit, sdk, is_sdk=True)
            elif '%precompiled_tag64%' in sdk.version:
                expand_category_param('%precompiled_tag64%', llvm_precompiled_tags_64bit, sdk, is_sdk=True)
            elif '%releases-tag%' in sdk.version:
                expand_category_param('%releases-tag%', releases_tags, sdk, is_sdk=True)
            else:
                add_sdk(sdk)


def can_simultaneously_activate(tool1, tool2):
    """Tests if the two given tools can be active at the same time.
    Currently only a simple check for name for same tool with different versions,
    possibly adds more logic in the future.
    """
    return tool1.id != tool2.id


def process_tool_list(tools_to_activate):
    """Expands dependencies for each tool, and removes ones that don't exist."""
    i = 0
    # Gather dependencies for each tool
    while i < len(tools_to_activate):
        tool = tools_to_activate[i]
        deps = tool.recursive_dependencies()
        tools_to_activate = tools_to_activate[:i] + deps + tools_to_activate[i:]
        i += len(deps) + 1

    for tool in tools_to_activate:
        if not tool.is_installed():
            exit_with_error(f"error: tool is not installed and therefore cannot be activated: '{tool}'")

    # Remove conflicting tools
    i = 0
    while i < len(tools_to_activate):
        j = 0
        while j < i:
            secondary_tool = tools_to_activate[j]
            primary_tool = tools_to_activate[i]
            if not can_simultaneously_activate(primary_tool, secondary_tool):
                tools_to_activate.pop(j)
                j -= 1
                i -= 1
            j += 1
        i += 1
    return tools_to_activate


def write_set_env_script(env_string):
    assert CMD or POWERSHELL
    write_file(EMSDK_SET_ENV, env_string)


def set_active_tools(tools_to_activate, permanently_activate, system):
    """Reconfigure .emscripten to choose the currently activated toolset, set PATH
    and other environment variables.
    Returns the full list of deduced tools that are now active.
    """
    tools_to_activate = process_tool_list(tools_to_activate)

    if tools_to_activate:
        tools = [x for x in tools_to_activate if not x.is_sdk]
        print('Setting the following tools as active:')
        for t in tools:
            print(f'   {t}')
        print('')

    generate_em_config(tools_to_activate, permanently_activate, system)

    # Construct a .bat or .ps1 script that will be invoked to set env. vars and PATH
    # We only do this on cmd or powershell since emsdk.bat/ps1 is able to modify the
    # calling shell environment.  On other shell `source emsdk_env.sh` is
    # required.
    if CMD or POWERSHELL:
        # always set local environment variables since permanently activating will only set the registry settings and
        # will not affect the current session
        env_vars_to_add = get_env_vars_to_add(tools_to_activate, system, user=permanently_activate)
        env_string = construct_env_with_vars(env_vars_to_add)
        write_set_env_script(env_string)

        if WINDOWS and permanently_activate:
            win_set_environment_variables(env_vars_to_add, system, user=permanently_activate)

    return tools_to_activate


def currently_active_sdk():
    for sdk in reversed(sdks):
        if sdk.is_active():
            return sdk
    return None


def currently_active_tools():
    active_tools = []
    for tool in tools:
        if tool.is_active():
            active_tools += [tool]
    return active_tools


# http://stackoverflow.com/questions/480214/how-do-you-remove-duplicates-from-a-list-in-python-whilst-preserving-order
def unique_items(seq):
    seen = set()
    seen_add = seen.add
    return [x for x in seq if x not in seen and not seen_add(x)]


def normalized_contains(lst, elem):
    """Tests if a path is contained in the given list, but with separators normalized."""
    elem = to_unix_path(elem)
    for e in lst:
        if elem == to_unix_path(e):
            return True
    return False


def to_msys_path(p):
    p = to_unix_path(p)
    new_path = re.sub(r'([a-zA-Z]):/(.*)', r'/\1/\2', p)
    if len(new_path) > 3 and new_path[0] == '/' and new_path[2] == '/':
        new_path = new_path[0] + new_path[1].lower() + new_path[2:]
    return new_path


def adjusted_path(tools_to_activate, system=False, user=False):
    """Looks at the current PATH and adds and removes entries so that the PATH reflects
    the set of given active tools.
    """
    # These directories should be added to PATH
    path_add = get_required_path(tools_to_activate)
    # These already exist.
    if WINDOWS and not MSYS:
        existing_path = win_get_environment_variable('PATH', system=system, user=user, fallback=True).split(ENVPATH_SEPARATOR)
    else:
        existing_path = os.environ['PATH'].split(ENVPATH_SEPARATOR)

    existing_emsdk_tools = []
    existing_nonemsdk_path = []
    for entry in existing_path:
        if to_unix_path(entry).startswith(EMSDK_PATH):
            existing_emsdk_tools.append(entry)
        else:
            existing_nonemsdk_path.append(entry)

    new_emsdk_tools = []
    kept_emsdk_tools = []
    for entry in path_add:
        if not normalized_contains(existing_emsdk_tools, entry):
            new_emsdk_tools.append(entry)
        else:
            kept_emsdk_tools.append(entry)

    whole_path = unique_items(new_emsdk_tools + kept_emsdk_tools + existing_nonemsdk_path)

    if MSYS:
        # XXX Hack: If running native Windows Python in MSYS prompt where PATH
        # entries look like "/c/Windows/System32", os.environ['PATH']
        # in Python will transform to show them as "C:\\Windows\\System32", so need
        # to reconvert path delimiter back to forward slashes.
        whole_path = [to_msys_path(p) for p in whole_path]
        new_emsdk_tools = [to_msys_path(p) for p in new_emsdk_tools]

    separator = ':' if MSYS else ENVPATH_SEPARATOR
    return (separator.join(whole_path), new_emsdk_tools)


def get_env_vars_to_add(tools_to_activate, system, user):
    env_vars_to_add = []

    newpath, added_path = adjusted_path(tools_to_activate, system, user)

    # Don't bother setting the path if there are no changes.
    if os.environ['PATH'] != newpath:
        env_vars_to_add += [('PATH', newpath)]

        if added_path:
            info('Adding directories to PATH:')
            for item in added_path:
                info('PATH += ' + item)
            info('')

    # A core variable EMSDK points to the root of Emscripten SDK directory.
    env_vars_to_add += [('EMSDK', EMSDK_PATH)]

    for tool in tools_to_activate:
        for env in tool.activated_environment():
            key, value = parse_key_value(env)
            value = to_native_path(tool.expand_vars(value))
            env_vars_to_add += [(key, value)]

    emroot = find_emscripten_root(tools_to_activate)
    if emroot:
        # For older emscripten versions that don't use an embedded cache by
        # default we need to export EM_CACHE.
        #
        # Sadly, we can't put this in the config file since those older versions
        # also didn't read the `CACHE` key from the config file:
        #
        # History:
        # - 'CACHE' config started being honored in 1.39.16
        #   https://github.com/emscripten-core/emscripten/pull/11091
        # - Default to embedded cache also started in 1.39.16
        #   https://github.com/emscripten-core/emscripten/pull/11126
        # - Emscripten supports automatically locating the embedded
        #   config in 1.39.13:
        #   https://github.com/emscripten-core/emscripten/pull/10935
        #
        # Since setting EM_CACHE in the environment effects the entire machine
        # we want to avoid this except when installing these older emscripten
        # versions that really need it.
        version = parse_emscripten_version(emroot)
        if version < [1, 39, 16]:
            em_cache_dir = os.path.join(emroot, 'cache')
            env_vars_to_add += [('EM_CACHE', em_cache_dir)]
        if version < [1, 39, 13]:
            env_vars_to_add += [('EM_CONFIG', os.path.normpath(EM_CONFIG_PATH))]

    return env_vars_to_add


def construct_env(tools_to_activate, system, user):
    info('Setting up EMSDK environment (suppress these messages with EMSDK_QUIET=1)')
    return construct_env_with_vars(get_env_vars_to_add(tools_to_activate, system, user))


def unset_env(key):
    if POWERSHELL:
        return f'Remove-Item env:{key} -ErrorAction SilentlyContinue\n'
    if CMD:
        return f'set {key}=\n'
    if CSH:
        return f'unsetenv {key};\n'
    if FISH:
        return f'set -e {key};\n'
    if BASH:
        return f'unset {key};\n'
    assert False


def construct_env_with_vars(env_vars_to_add):
    env_string = ''
    if env_vars_to_add:
        info('Setting environment variables:')

        for key, value in env_vars_to_add:
            # Don't set env vars which are already set to the correct value.
            if key in os.environ and to_unix_path(os.environ[key]) == to_unix_path(value):
                continue
            info(f'{key} = {value}')
            if POWERSHELL:
                env_string += f'$env:{key}="{value}"\n'
            elif CMD:
                env_string += f'SET {key}={value}\n'
            elif CSH:
                env_string += f'setenv {key} "{value}";\n'
            elif FISH:
                env_string += f'set -gx {key} "{value}";\n'
            elif BASH:
                env_string += f'export {key}="{value}";\n'
            else:
                assert False

        if 'EMSDK_PYTHON' in env_vars_to_add:
            # When using our bundled python we never want the user's
            # PYTHONHOME or PYTHONPATH
            # See https://github.com/emscripten-core/emsdk/issues/598
            env_string += unset_env('PYTHONHOME')
            env_string += unset_env('PYTHONPATH')

    # Remove any environment variables that might have been set by old or
    # inactive tools/sdks.  For example, we set EM_CACHE for older versions
    # of the SDK but we want to remove that from the current environment
    # if no such tool is active.
    # Ignore certain keys that are inputs to emsdk itself.
    ignore_keys = {'EMSDK_POWERSHELL', 'EMSDK_CSH', 'EMSDK_CMD', 'EMSDK_BASH', 'EMSDK_FISH',
                   'EMSDK_NUM_CORES', 'EMSDK_NOTTY', 'EMSDK_KEEP_DOWNLOADS'}
    env_keys_to_add = {pair[0] for pair in env_vars_to_add}
    for key in os.environ:
        if key.startswith('EMSDK_') or key in {'EM_CACHE', 'EM_CONFIG'}:
            if key not in env_keys_to_add and key not in ignore_keys:
                info(f'Clearing existing environment variable: {key}')
                env_string += unset_env(key)

    return env_string


def error_on_missing_tool(name):
    if name.endswith('-64bit') and not is_os_64bit():
        exit_with_error(f"'{name}' is only provided for 64-bit OSes")
    else:
        exit_with_error(f"tool or SDK not found: '{name}'")


def expand_sdk_name(name, activating):
    if 'upstream-master' in name:
        errlog('upstream-master SDK has been renamed main')
        name = name.replace('upstream-master', 'main')
    if 'fastcomp' in name:
        exit_with_error('the fastcomp backend is no longer supported. '
                        'Please use an older version of emsdk (for example 3.1.29) '
                        'if you want to install the old fastcomp-based SDK')
    if name in {'tot', 'sdk-tot', 'tot-upstream'}:
        if activating:
            # When we are activating a tot release, assume that the currently
            # installed SDK, if any, is the tot release we want to activate.
            # Without this `install tot && activate tot` will race with the builders
            # that are producing new builds.
            installed = get_installed_sdk_version()
            if installed:
                debug_print('activating currently installed SDK; not updating tot version')
                return f'sdk-releases-{installed}-64bit'
        return find_tot_sdk()

    if '-upstream' in name:
        name = name.replace('-upstream', '')

    name = resolve_sdk_aliases(name, verbose=True)

    # check if it's a release handled by an emscripten-releases version,
    # and if so use that by using the right hash. we support a few notations,
    #   x.y.z
    #   sdk-x.y.z-64bit
    # TODO: support short notation for old builds too?
    fullname = name
    version = fullname.replace('sdk-', '').replace('releases-', '').replace('-64bit', '').replace('tag-', '')
    sdk = 'sdk-' if not name.startswith('releases-') else ''
    releases_info = load_releases_info()['releases']
    release_hash = get_release_hash(version, releases_info)
    if release_hash:
        # Known release hash
        full_name = f'{sdk}releases-{release_hash}-64bit'
        print(f"Resolving SDK version '{version}' to '{full_name}'")
        return full_name

    if len(version) == 40:
        global extra_release_tag
        extra_release_tag = version
        return f'{sdk}releases-{version}-64bit'

    return name


def main(args):  # ruff: ignore[complex-structure, too-many-return-statements, too-many-branches]
    if not args:
        errlog("Missing command; Type 'emsdk help' to get a list of commands.")
        return 1

    debug_print(f'emsdk.py running under `{sys.executable}`')
    cmd = args.pop(0)

    if cmd in {'help', '--help', '-h'}:
        print(' emsdk: Available commands:')

        print('''
       emsdk list [--old] [--deps]  - Lists all available SDKs and tools and their
                                      current installation status. With the --old
                                      parameter, also historical versions are
                                      shown. If --deps is passed, displays the
                                      composition of different SDK packages and
                                      dependencies.

       emsdk update                 - Updates emsdk to the newest version. If you have
                                      bootstrapped emsdk via cloning directly from
                                      GitHub, call "git pull" instead to update emsdk.

       emsdk install [options] <tool 1> <tool 2> <tool 3> ...
                                    - Downloads and installs given tools or SDKs.
                                      Options can contain:

                             -j<num>: Specifies the number of cores to use when
                                      building the tool. Default: use one less
                                      than the # of detected cores.

                      --build=<type>: Controls what kind of build of LLVM to
                                      perform. Pass either 'Debug', 'Release',
                                      'MinSizeRel' or 'RelWithDebInfo'. Default:
                                      'Release'.

                  --generator=<type>: Specifies the CMake Generator to be used
                                      during the build. Possible values are the
                                      same as what your CMake supports and whether
                                      the generator is valid depends on the tools
                                      you have installed. Defaults to 'Unix Makefiles'
                                      on *nix systems. If generator name is multiple
                                      words, enclose with single or double quotes.

                           --shallow: When installing tools from one of the git
                                      development branches, this parameter can be
                                      passed to perform a shallow git clone instead
                                      of a full one.  This reduces the amount of
                                      network transfer that is needed. This option
                                      should only be used when you are interested in
                                      downloading one of the development branches,
                                      but are not looking to develop Emscripten
                                      yourself.  Default: disabled, i.e. do a full
                                      clone.

                       --build-tests: If enabled, LLVM is built with internal tests
                                      included. Pass this to enable running test
                                      other.test_llvm_lit in the Emscripten test
                                      suite. Default: disabled.
                 --enable-assertions: If specified, LLVM is built with assert()
                                      checks enabled. Useful for development
                                      purposes. Default: Enabled
                --disable-assertions: Forces assertions off during the build.

                   --vs2019/--vs2022: If building from source, overrides to build
                                      using the specified compiler. When installing
                                      precompiled packages, this has no effect.
                                      Note: The same compiler specifier must be
                                      passed to the emsdk activate command to
                                      activate the desired version.

                                      Notes on building from source:

                                      To pass custom CMake directives when configuring
                                      LLVM build, specify the environment variable
                                      LLVM_CMAKE_ARGS="param1=value1,param2=value2"
                                      in the environment where the build is invoked.
                                      See README.md for details.

               --override-repository: Specifies the git URL to use for a given Tool. E.g.
                                      --override-repository emscripten-main@https://github.com/<fork>/emscripten/tree/<refspec>


       emsdk deactivate tool/sdk    - Removes the given tool or SDK from the current set of activated tools.


       emsdk uninstall <tool/sdk>   - Removes the given tool or SDK from disk.''')

        if WINDOWS:
            print('''
         emsdk activate [--permanent] [--system] [--build=type] [--vs2019/--vs2022] <tool/sdk>

                                      - Activates the given tool or SDK in the
                                        environment of the current shell.

                                      - If the `--permanent` option is passed, then the environment
                                        variables are set permanently for the current user.

                                      - If the `--system` option is passed, the registration
                                        is done for all users of the system.
                                        This needs admin privileges
                                        (uses Machine environment variables).

                                      - If a custom compiler version was used to override
                                        the compiler to use, pass the same --vs2019/--vs2022
                                        parameter here to choose which version to activate.

         emcmdprompt.bat              - Spawns a new command prompt window with the
                                        Emscripten environment active.''')
        else:
            print('''   emsdk activate [--build=type] <tool/sdk>

                                      - Activates the given tool or SDK in the
                                        environment of the current shell.''')

        print('''
           Both commands 'install' and 'activate' accept an optional parameter
           '--build=type', which can be used to override what kind of installation
           or activation to perform. Possible values for type are Debug, Release,
           MinSizeRel or RelWithDebInfo. Note: When overriding a custom build type,
           be sure to match the same --build= option to both 'install' and
           'activate' commands and the invocation of 'emsdk_env', or otherwise
           these commands will default to operating on the default build type
           which is RelWithDebInfo.''')

        print('''

       Environment:
          EMSDK_KEEP_DOWNLOADS=1     - if you want to keep the downloaded archives.
          EMSDK_NOTTY=1              - override isatty() result (mainly to log progress).
          EMSDK_NUM_CORES=n          - limit parallelism to n cores.
          EMSDK_VERBOSE=1            - very verbose output, useful for debugging.
          EMSDK_RETRY_CLEAN_BUILD=1  - performs a clean rebuild of compiled tools if
                                       incremental build fails. Useful on CI.''')
        return 0

    def extract_bool_arg(name):
        """Extracts a boolean command line argument from args and returns True if it was present"""
        if name in args:
            args.remove(name)
            return True
        return False

    def extract_string_arg(name):
        for i in range(len(args)):
            if args[i] == name:
                value = args[i + 1]
                del args[i:i + 2]
                return value

    arg_old = extract_bool_arg('--old')
    arg_deps = extract_bool_arg('--deps')
    arg_permanent = extract_bool_arg('--permanent')
    arg_global = extract_bool_arg('--global')
    arg_system = extract_bool_arg('--system')
    if arg_global:
        print('--global is deprecated. Use `--system` to set the environment variables for all users')
        arg_system = True
    if arg_system:
        arg_permanent = True
    if extract_bool_arg('--embedded'):
        errlog('embedded mode is now the only mode available')
    if extract_bool_arg('--no-embedded'):
        errlog('embedded mode is now the only mode available')
        return 1

    arg_notty = extract_bool_arg('--notty')
    if arg_notty:
        global TTY_OUTPUT
        TTY_OUTPUT = False

    # Replace meta-packages with the real package names.
    if cmd in {'update', 'install', 'activate'}:
        activating = cmd == 'activate'
        args = [expand_sdk_name(a, activating=activating) for a in args]

    load_em_config()
    load_sdk_manifest()

    # Apply any overrides to git branch names to clone from.
    forked_url = extract_string_arg('--override-repository')
    while forked_url:
        tool_name, url_and_refspec = forked_url.split('@')
        t = find_tool(tool_name)
        if not t:
            errlog(f'Failed to find tool {tool_name}')
            return False
        else:
            t.url, t.git_branch, t.remote_name = parse_github_url_and_refspec(url_and_refspec)
            debug_print(f'Reading git repository URL "{t.url}" and git branch "{t.git_branch}" for Tool "{tool_name}".')

        forked_url = extract_string_arg('--override-repository')

    # Process global args
    for i in range(len(args)):
        if args[i].startswith('--generator='):
            build_generator = re.match(r'''^--generator=['"]?([^'"]+)['"]?$''', args[i])
            if build_generator:
                global CMAKE_GENERATOR
                CMAKE_GENERATOR = build_generator.group(1)
                args[i] = ''
            else:
                errlog(f"Cannot parse CMake generator string: {args[i]}. Try wrapping generator string with quotes")
                return 1
        elif args[i].startswith('--build='):
            build_type = re.match(r'^--build=(.+)$', args[i])
            if build_type:
                global CMAKE_BUILD_TYPE_OVERRIDE
                build_type = build_type.group(1)
                build_types = ['Debug', 'MinSizeRel', 'RelWithDebInfo', 'Release']
                try:
                    build_type_index = [x.lower() for x in build_types].index(build_type.lower())
                    CMAKE_BUILD_TYPE_OVERRIDE = build_types[build_type_index]
                    args[i] = ''
                except Exception:
                    errlog(f'Unknown CMake build type "{build_type}" specified! Please specify one of {build_types}')
                    return 1
            else:
                errlog(f'Invalid command line parameter {args[i]} specified!')
                return 1
    args = [x for x in args if x]

    if cmd == 'list':
        print('')

        def installed_sdk_text(name):
            sdk = find_sdk(name)
            return 'INSTALLED' if sdk and sdk.is_installed() else ''

        if (LINUX or MACOS or WINDOWS) and ARCH in {'x86', 'x86_64'}:
            print(f'The *recommended* precompiled SDK download is {find_latest_version()} ({find_latest_hash()}).')
            print()
            print('To install/activate it use:')
            print('         latest')
            print('')
            print('This is equivalent to installing/activating:')
            print(f'         {find_latest_version()}             {installed_sdk_text(find_latest_sdk())}')
            print('')
        else:
            print('Warning: your platform does not have precompiled SDKs available.')
            print('You may install components from source.')
            print('')

        print('All recent (non-legacy) installable versions are:')
        releases_versions = sorted(load_releases_versions(), key=version_key, reverse=True)
        releases_info = load_releases_info()['releases']
        for ver in releases_versions:
            sdk_name = f'sdk-releases-{get_release_hash(ver, releases_info)}-64bit'
            print(f'         {ver}    {installed_sdk_text(sdk_name)}')
        print()

        # Use array to work around the lack of being able to mutate from enclosing
        # function.
        has_partially_active_tools = [False]

        if sdks:
            def find_sdks(needs_compilation):
                s = []
                for sdk in sdks:
                    if sdk.is_old and not arg_old:
                        continue
                    if sdk.needs_compilation() == needs_compilation:
                        s += [sdk]
                return s

            def print_sdks(s):
                for sdk in s:
                    installed = '\tINSTALLED' if sdk.is_installed() else ''
                    active = '*' if sdk.is_active() else ' '
                    print(f'    {active}    {sdk!s: <25}{installed}')
                    if arg_deps:
                        for dep in sdk.deps:
                            print(f'          - {dep: <25}')
                print('')
            print('The additional following precompiled SDKs are also available for download:')
            print_sdks(find_sdks(False))

            print('The following SDKs can be compiled from source:')
            print_sdks(find_sdks(True))

        if tools:
            def find_tools(needs_compilation):
                t = []
                for tool in tools:
                    if tool.is_old and not arg_old:
                        continue
                    if tool.needs_compilation() != needs_compilation:
                        continue
                    t += [tool]
                return t

            def print_tools(t):
                for tool in t:
                    if tool.is_old and not arg_old:
                        continue
                    if tool.can_be_installed() is True:
                        installed = '\tINSTALLED' if tool.is_installed() else ''
                    else:
                        installed = '\tNot available: ' + tool.can_be_installed()
                    tool_is_active = tool.is_active()
                    tool_is_env_active = tool_is_active and tool.is_env_active()
                    if tool_is_env_active:
                        active = ' * '
                    elif tool_is_active:
                        active = '(*)'
                        has_partially_active_tools[0] = has_partially_active_tools[0] or True
                    else:
                        active = '   '
                    print(f'    {active}    {tool!s: <25}{installed}')
                print('')

            print('The following precompiled tool packages are available for download:')
            print_tools(find_tools(needs_compilation=False))
            print('The following tools can be compiled from source:')
            print_tools(find_tools(needs_compilation=True))
        else:
            if is_emsdk_sourced_from_github():
                print("There are no tools available. Run 'git pull' to fetch the latest set of tools.")
            else:
                print("There are no tools available. Run 'emsdk update' to fetch the latest set of tools.")
            print('')

        print('Items marked with * are activated for the current user.')
        if has_partially_active_tools[0]:
            env_cmd = 'emsdk_env.bat' if WINDOWS else 'source ./emsdk_env.sh'
            print('Items marked with (*) are selected for use, '
                  'but your current shell environment is not configured to use them. '
                  f'Type "{env_cmd}" to set up your current shell to use them' +
                  (', or call "emsdk activate --permanent <name_of_sdk>" to permanently activate them.' if WINDOWS else '.'))
        if not arg_old:
            print('')
            print("To access the historical archived versions, type 'emsdk list --old'")

        print('')
        if is_emsdk_sourced_from_github():
            print('Run "git pull" to pull in the latest list.')
        else:
            print('Run "./emsdk update" to pull in the latest list.')

        return 0
    elif cmd == 'construct_env':
        # Clean up old temp file up front, in case of failure later before we get
        # to write out the new one.
        tools_to_activate = currently_active_tools()
        tools_to_activate = process_tool_list(tools_to_activate)
        env_string = construct_env(tools_to_activate, arg_system, arg_permanent)
        if CMD or POWERSHELL:
            write_set_env_script(env_string)
        else:
            sys.stdout.write(env_string)
        return 0
    elif cmd == 'update':
        update_emsdk()
        if WINDOWS:
            # Clean up litter after old emsdk update which may have left this temp
            # file around.
            rmfile(sdk_path(EMSDK_SET_ENV))
        return 0
    elif cmd == 'update-tags':
        errlog('`update-tags` is not longer needed.  To install the latest tot release just run `install tot`')
        return 0
    elif cmd in {'activate', 'deactivate'}:
        if arg_permanent:
            print('Registering active Emscripten environment permanently')
            print('')

        tools_to_activate = currently_active_tools()
        for arg in args:
            tool = find_tool(arg)
            if tool is None:
                tool = find_sdk(arg)
                if tool is None:
                    error_on_missing_tool(arg)

            if cmd == 'activate':
                tools_to_activate += [tool]
            elif tool in tools_to_activate:
                print(f'Deactivating tool {tool}.')
                tools_to_activate.remove(tool)
            else:
                print(f'Tool "{arg}" was not active, no need to deactivate.')
        if not tools_to_activate:
            errlog('No tools/SDKs specified to activate! Usage:\n   emsdk activate tool/sdk1 [tool/sdk2] [...]')
            return 1
        active_tools = set_active_tools(tools_to_activate, permanently_activate=arg_permanent, system=arg_system)
        if not active_tools:
            errlog('No tools/SDKs found to activate! Usage:\n   emsdk activate tool/sdk1 [tool/sdk2] [...]')
            return 1
        if WINDOWS and not arg_permanent:
            errlog('The changes made to environment variables only apply to the currently running shell instance. '
                   'Use the \'emsdk_env.bat\' to re-enter this environment later, '
                   'or if you\'d like to register this environment permanently, rerun this command with the option --permanent.')
        return 0
    elif cmd == 'install':
        global BUILD_FOR_TESTING, ENABLE_LLVM_ASSERTIONS, CPU_CORES, GIT_CLONE_SHALLOW

        # Process args
        for i in range(len(args)):
            if args[i].startswith('-j'):
                multicore = re.match(r'^-j(\d+)$', args[i])
                if multicore:
                    CPU_CORES = int(multicore.group(1))
                    args[i] = ''
                else:
                    errlog(f'Invalid command line parameter {args[i]} specified!')
                    return 1
            elif args[i] == '--shallow':
                GIT_CLONE_SHALLOW = True
                args[i] = ''
            elif args[i] == '--build-tests':
                BUILD_FOR_TESTING = True
                args[i] = ''
            elif args[i] == '--enable-assertions':
                ENABLE_LLVM_ASSERTIONS = 'ON'
                args[i] = ''
            elif args[i] == '--disable-assertions':
                ENABLE_LLVM_ASSERTIONS = 'OFF'
                args[i] = ''
        args = [x for x in args if x]
        if not args:
            errlog("Missing parameter. Type 'emsdk install <tool name>' to install a tool or an SDK. "
                   "Type 'emsdk list' to obtain a list of available tools. "
                   "Type 'emsdk install latest' to automatically install the newest version of the SDK.")
            return 1

        if LINUX and ARCH == 'arm64' and args != ['latest']:
            errlog('WARNING: arm64-linux binaries are not available for all releases.')
            errlog('See https://github.com/emscripten-core/emsdk/issues/547')

        for t in args:
            tool = find_tool(t)
            if tool is None:
                tool = find_sdk(t)
            if tool is None:
                error_on_missing_tool(t)
            tool.install()
        return 0
    elif cmd == 'uninstall':
        if not args:
            errlog("Syntax error. Call 'emsdk uninstall <tool name>'. Call 'emsdk list' to obtain a list of available tools.")
            return 1
        tool = find_tool(args[0])
        if tool is None:
            errlog(f"Error: Tool by name '{args[0]}' was not found.")
            return 1
        tool.uninstall()
        return 0

    errlog(f"Unknown command '{cmd}' given! Type 'emsdk help' to get a list of commands.")
    return 1


if __name__ == '__main__':
    try:
        sys.exit(main(sys.argv[1:]))
    except KeyboardInterrupt:
        exit_with_error('aborted by user, exiting')
        sys.exit(1)
