#!/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('error: %s' % 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', '[%s.0,%s.0)' % (version, version + 1), '-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("Downloading: %s from %s" % (file_name, 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("Downloading: %s from %s, %s Bytes" % (file_name, url, file_size))
  else:
    print("Downloading: %s from %s" % (file_name, 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 = r" %10d  [%3.02f%%]" % (file_size_dl, percent)
                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('finished downloading (%d bytes)' % file_size_dl)


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 (see http://stackoverflow.com/questions/9329243/xcode-4-4-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}, 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() != 'release' and build_type.lower() != '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'), '''\
# Set maximum cache size to 10 GB:
max_size = 10G
cache_dir = %s
''' % 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('Error running %s' % str(e))
      return False

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

  return True


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


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


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


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

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

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

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

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

  return success


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

  url = urljoin(emsdk_packages_url, archive)

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

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

  if not success:
    success = try_download(url)

  if not success:
    return False

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

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


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


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


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


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


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


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

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


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

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


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


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

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


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

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

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

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


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


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

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

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

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

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

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

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

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

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

  write_file(EM_CONFIG_PATH, cfg)

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

  path_add = get_required_path(active_tools)

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


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

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

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

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

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

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

  def __str__(self):
    return self.name

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

    return str

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  def dependencies(self):
    deps = []

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

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


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


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


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


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


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

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


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


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


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


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


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


def find_latest_sdk():
  return 'sdk-releases-%s-64bit' % (find_latest_hash())


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


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("error: tool is not installed and therefore cannot be activated: '%s'" % tool)

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


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


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

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

  generate_em_config(tools_to_activate, permanently_activate, system)

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

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

  return tools_to_activate


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


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


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


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


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


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

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

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

  whole_path = unique_items(new_emsdk_tools + kept_emsdk_tools + existing_nonemsdk_path)

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

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


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

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

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

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

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

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

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

  return env_vars_to_add


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


def unset_env(key):
  if POWERSHELL:
    return 'Remove-Item env:%s -ErrorAction SilentlyContinue\n' % key
  if CMD:
    return 'set %s=\n' % key
  if CSH:
    return 'unsetenv %s;\n' % key
  if FISH:
    return 'set -e %s;\n' % key
  if BASH:
    return 'unset %s;\n' % key
  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('Clearing existing environment variable: %s' % 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("'%s' is only provided for 64-bit OSes" % name)
  else:
    exit_with_error("tool or SDK not found: '%s'" % 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 'sdk-releases-%s-64bit' % installed
    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 = '%sreleases-%s-64bit' % (sdk, release_hash)
    print("Resolving SDK version '%s' to '%s'" % (version, full_name))
    return full_name

  if len(version) == 40:
    global extra_release_tag
    extra_release_tag = version
    return '%sreleases-%s-64bit' % (sdk, version)

  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('emsdk.py running under `%s`' % sys.executable)
  cmd = args.pop(0)

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

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

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

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

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

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

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

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

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

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

                                  Notes on building from source:

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

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


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


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

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

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

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

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

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

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

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

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

    print('''

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

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

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

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

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

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

  load_em_config()
  load_sdk_manifest()

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

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

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

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

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

    if (LINUX or MACOS or WINDOWS) and ARCH in {'x86', 'x86_64'}:
      print('The *recommended* precompiled SDK download is %s (%s).' % (find_latest_version(), find_latest_hash()))
      print()
      print('To install/activate it use:')
      print('         latest')
      print('')
      print('This is equivalent to installing/activating:')
      print('         %s             %s' % (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:
      print('         %s    %s' % (ver, installed_sdk_text('sdk-releases-%s-64bit' % get_release_hash(ver, releases_info))))
    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('    ' + active + '    {0: <25}'.format(str(sdk)) + installed)
          if arg_deps:
            for dep in sdk.deps:
              print('          - {0: <25}'.format(dep))
        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('    ' + active + '    {0: <25}'.format(str(tool)) + 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(f'Items marked with (*) are selected for use, but your current shell environment is not configured to use them. 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)
