#!/usr/bin/env python3
"""Bootstrap script for emscripten developers / git users.

After checking out emscripten there are certain steps that need to be
taken before it can be used.  This script enumerates and automates
these steps and is able to run just the steps that are needed based
on the timestamps of various input files (kind of like a dumb version
of a Makefile).
"""
import argparse
import os
import shutil
import subprocess
import sys

__rootdir__ = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, __rootdir__)

STAMP_DIR = os.path.join(__rootdir__, 'out')

# N.b. This script bootstrap.py cannot use 'from tools import shared',
# because shared.py requires that a valid .emscripten config is already
# created. Bootstrap.py needs to be run before an .emscripten config exists.
from tools import utils


def get_stamp_file(action_name):
  return os.path.join(STAMP_DIR, action_name.replace(' ', '_') + '.stamp')


def check_deps(name, deps):
  stamp_file = get_stamp_file(name)
  if not os.path.exists(stamp_file):
    return False
  for dep in deps:
    dep = utils.path_from_root(dep)
    if os.path.getmtime(dep) > os.path.getmtime(stamp_file):
      return False
  return True


def check():
  for name, deps, _ in actions:
    if not check_deps(name, deps):
      utils.exit_with_error(f'emscripten setup is not complete ("{name}" is out-of-date). Run `bootstrap.py` to update')


def ask_yes_no(question):
  while True:
    try:
      reply = input(f"{question} (y/n): ").strip().lower()
    except EOFError:
      return False

    if reply in {'y', 'yes'}:
      return True
    if reply in {'n', 'no'}:
      return False

    print("Invalid input. Please enter 'y' or 'n'.")


def maybe_install_hooks():
  if os.path.exists('.git/hooks/pre-push'):
    print('git hooks already installed; skipping')
    return
  if os.environ.get('CI') or not sys.stdin.isatty():
    # Do nothing when running in CI or non-interactive shell
    return
  if ask_yes_no('Install emscripten git hooks (see tools/maint/git-hooks)?'):
    install_hooks()


def install_hooks():
  if not os.path.exists(utils.path_from_root('.git')):
    print('--install-git-hooks requires a git checkout')
    return 1

  dst = utils.path_from_root('.git/hooks')
  if not os.path.exists(dst):
    os.mkdir(dst)

  for src in ('tools/maint/git-hooks/post-checkout', 'tools/maint/git-hooks/pre-push'):
    shutil.copy(utils.path_from_root(src), dst)
  return 0


def run_cmd(cmd):
  orig_exe = cmd[0]
  if not os.path.isabs(orig_exe):
    cmd[0] = shutil.which(orig_exe)
    if not cmd[0]:
      utils.exit_with_error(f'command not found: {orig_exe}')
  print(f" -> {' '.join(cmd)}")
  subprocess.run(cmd, check=True, text=True, encoding='utf-8', cwd=utils.path_from_root())


actions = [
  ('npm packages', [
     'package.json',
     'package-lock.json',
   ], ['npm', 'ci']),
  ('create entry points', [
     'tools/maint/create_entry_points.py',
     'tools/pylauncher/pylauncher.exe',
     'tools/pylauncher/pylauncher-arm64.exe',
     'tools/maint/run_python.sh',
     'tools/maint/run_python_compiler.sh',
   ], [sys.executable, 'tools/maint/create_entry_points.py']),
  ('git submodules', [
     'test/third_party/posixtestsuite/',
     'test/third_party/googletest',
     'test/third_party/wasi-test-suite',
   ], ['git', 'submodule', 'update', '--init']),
  ('install hooks', [
     'tools/maint/git-hooks/post-checkout',
     'tools/maint/git-hooks/pre-push',
   ], maybe_install_hooks),
]


def enable_emsdk_node():
  # By default emsdk avoids prepending its node binary to PATH if another node
  # is already present. For running bootstrap actions (like `npm ci`), however,
  # we prefer the emsdk-provided node (and npm) because the system node might
  # be an incompatible version or lack npm.
  # Other emscripten tools can rely on the config file to find node so do not
  # need to do this.
  emsdk_node = os.environ.get('EMSDK_NODE')
  if emsdk_node:
    node_dir = os.path.dirname(emsdk_node)
    os.environ['PATH'] = node_dir + os.pathsep + os.environ['PATH']


def main(args):
  parser = argparse.ArgumentParser(description=__doc__)
  parser.add_argument('-v', '--verbose', action='store_true', help='verbose', default=False)
  parser.add_argument('-f', '--force', action='store_true', help='force all actions to run', default=False)
  parser.add_argument('-n', '--dry-run', action='store_true', help='dry run', default=False)
  parser.add_argument('-i', '--install-git-hooks', action='store_true', help='install emscripten git hooks', default=False)
  args = parser.parse_args()

  if args.install_git_hooks:
    return install_hooks()

  enable_emsdk_node()

  for name, deps, action in actions:
    if not args.force:
      if check_deps(name, deps):
        print(f'Up-to-date: {name}')
        continue
      print(f'Out-of-date: {name}')
    if args.dry_run:
      if isinstance(action, list):
        action_str = ' '.join(action)
      else:
        action_str = action.__name__
      print(f' (skipping: dry run) -> {action_str}')
      continue
    if isinstance(action, list):
      run_cmd(action)
    else:
      action()
    utils.safe_ensure_dirs(STAMP_DIR)
    stamp_file = get_stamp_file(name)
    utils.write_file(stamp_file, 'Timestamp file created by bootstrap.py')
  return 0


if __name__ == '__main__':
  main(sys.argv[1:])
