#!/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")
ACTIVATED_JSON_PATH = os.path.join(EMSDK_PATH, "activated.json")
ACTIVATED_TOOLS = set()


def get_active_legacy():
    """Legacy support for users without existing `activated.json` files.

    Older versions of emsdk would imply active status purely based on the
    emscripten config file.  This function uses that old method to generate
    an initial `activated.json` state.
    """
    if not os.path.exists(EM_CONFIG_PATH):
        return []

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

    em_config_dict = load_em_config()

    def is_active_legacy(tool):
        if not tool.is_installed():
            return False

        deps = tool.dependencies()
        for dep in deps:
            if not is_active_legacy(dep):
                return False

        activated_cfg = tool.activated_config()
        if tool.legacy_cfg:
            name, value = to_unix_path(tool.expand_vars(tool.legacy_cfg)).split('=')
            activated_cfg[name] = value.strip("'")

        if not activated_cfg:
            return len(deps) > 0

        for key, value in activated_cfg.items():
            if key not in em_config_dict:
                return False
            config_value = em_config_dict[key].replace("emsdk_path + '", "'" + EMSDK_PATH).replace("$CFGDIR", EMSDK_PATH).strip("'")
            if config_value != value:
                return False

        return True

    active = []
    for sdk in sdks:
        if is_active_legacy(sdk):
            active.append(sdk)
    for tool in tools:
        if is_active_legacy(tool):
            active.append(tool)

    return active


def load_activated_json():
    ACTIVATED_TOOLS.clear()
    if not os.path.exists(ACTIVATED_JSON_PATH):
        save_activated_json(get_active_legacy())
        return

    try:
        data = json.loads(read_file(ACTIVATED_JSON_PATH))
        assert isinstance(data, dict), f'Expected dict in {ACTIVATED_JSON_PATH}'
        ACTIVATED_TOOLS.update(data.get('active_tools', []))
    except Exception as e:
        errlog(f'warning: failed to parse {ACTIVATED_JSON_PATH}: {e}')


def save_activated_json(active_tools):
    names = sorted(unique_items([str(t) for t in active_tools]))
    data = {'active_tools': names}
    write_file(ACTIVATED_JSON_PATH, json.dumps(data, indent=2) + '\n')
    # Now re-load the newly generated file to update the `ACTIVATED_TOOLS` global state.
    load_activated_json()


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 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
    legacy_cfg = None
    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

        return str(self) in ACTIVATED_TOOLS

    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)
    save_activated_json(tools_to_activate)

    # 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_sdk_manifest()
    load_activated_json()

    # 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)
