#!/usr/bin/env python3
import glob
import json
import os
import platform
import shutil
import stat
import subprocess
import sys
import tempfile
import unittest

WINDOWS = sys.platform.startswith('win')
MACOS = sys.platform == 'darwin'
MACOS_ARM64 = MACOS and platform.machine() == 'arm64'

emconfig = os.path.abspath('.emscripten')
assert os.path.exists(emconfig)

if WINDOWS:
  emsdk = 'emsdk.bat'
else:
  emsdk = './emsdk'

# Utilities


def listify(x):
  if type(x) in {list, tuple}:
    return x
  return [x]


def copy_emsdk_to(targetdir):
  for filename in os.listdir('.'):
    if not filename.startswith('.') and not os.path.isdir(filename):
      shutil.copy2(filename, os.path.join(targetdir, filename))


def check_call(cmd, **kwargs):
  if type(cmd) is not list:
    cmd = cmd.split()
  print('running: %s' % cmd)
  subprocess.run(cmd, check=True, text=True, **kwargs)


def checked_call_with_output(cmd, expected=None, unexpected=None, stderr=None, env=None):
  cmd = cmd.split(' ')
  print('running: %s' % cmd)
  try:
    stdout = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=stderr, check=True, text=True, env=env).stdout
  except subprocess.CalledProcessError as e:
    print(e.stderr)
    print(e.stdout)
    raise e

  if expected:
    for x in listify(expected):
      assert x in stdout, 'expected output missing: ' + stdout + '\n[[[' + x + ']]]'
  if unexpected:
    for x in listify(unexpected):
      assert x not in stdout, 'unexpected output present: ' + stdout + '\n[[[' + x + ']]]'


def failing_call_with_output(cmd, expected, env=None):
  proc = subprocess.run(cmd.split(' '), capture_output=True, text=True, env=env)
  stdout = proc.stdout
  stderr = proc.stderr
  if WINDOWS:
    print('warning: skipping part of failing_call_with_output() due to error codes not being propagated (see #592)')
  else:
    assert proc.returncode, 'call must have failed: ' + str([stdout, '\n========\n', stderr])
  assert expected in stdout or expected in stderr, 'call did not have the expected output: %s: %s' % (expected, str([stdout, '\n========\n', stderr]))


def hack_emsdk(marker, replacement):
  with open('emsdk.py') as f:
    src = f.read()
  assert marker in src
  src = src.replace(marker, replacement)
  name = '__test_emsdk'
  with open(name, 'w') as f:
    f.write(src)
  return name


def get_longest_path_in_dir(dirname):
  longest = ''
  for root, _dirs, files in os.walk(dirname):
    for f in files:
      fullname = os.path.join(root, f)
      if len(fullname) > len(longest):
        longest = fullname
  return longest


def remove_file(filename):
  if os.path.exists(filename):
    os.remove(filename)


def remove_tree(path):
  if not os.path.exists(path):
    return
  if WINDOWS:
    path = '\\\\?\\' + path

  def remove_readonly(func, path2, _):
    os.chmod(path2, stat.S_IRWXU)
    func(path2)

  shutil.rmtree(path, onerror=remove_readonly)


# Set up

TAGS = json.loads(open('emscripten-releases-tags.json').read())

# Tests


def do_lib_building(emcc):
  cache_building_messages = ['generating system library: ']

  def do_build(args, is_expected=None):
    unexpected = None
    expected = None
    if is_expected is True:
      expected = cache_building_messages
    elif is_expected is False:
      unexpected = cache_building_messages
    checked_call_with_output(emcc + ' hello_world.c' + args,
                             expected=expected,
                             unexpected=unexpected,
                             stderr=subprocess.STDOUT)

  # The emsdk ships all system libraries so we don't expect to see any
  # cache population unless we explicly --clear-cache.
  do_build('', is_expected=False)
  check_call(emcc + ' --clear-cache')
  do_build(' -O2', is_expected=True)
  # Do another build at -O0.  In nwers SDK versions this generates
  # different libs, but not in older ones so don't assert here.
  do_build('')
  # Now verify that libs are *not* build
  do_build(' -s WASM=0', is_expected=False)
  do_build(' -O2 -s WASM=0', is_expected=False)


def run_emsdk(cmd):
  if type(cmd) is not list:
    cmd = cmd.split()
  check_call([emsdk, *cmd])


def upstream_emcc(root='.'):
  emcc = os.path.join(root, 'upstream', 'emscripten', 'emcc')
  if WINDOWS:
    if os.path.exists(emcc + '.exe'):
      return emcc + '.exe'
    else:
      return emcc + '.bat'
  return emcc


class Emsdk(unittest.TestCase):
  def setUp(self):
    run_emsdk('install latest')
    run_emsdk('activate latest')
    with open('hello_world.c', 'w') as f:
      f.write('''\
#include <stdio.h>

int main() {
   printf("Hello, world!\\n");
   return 0;
}
''')
    self.addCleanup(remove_file, 'hello_world.c')

  def tearDown(self):
    for f in glob.glob('a.out*'):
      os.remove(f)

  def test_extrememly_long_filenames(self):
    # We have special support for filenames longer than 256 on windows. This
    # test installs emsdk in path that exceeds this limit in order to test
    # this handling.
    longpath = os.path.abspath('very_long_filename_indeed')

    additional = 140 - len(longpath)
    longpath += 'x' * additional

    remove_tree(longpath)
    self.addCleanup(remove_tree, longpath)

    os.makedirs(longpath)
    copy_emsdk_to(longpath)

    emsdk = os.path.join(longpath, 'emsdk')
    if WINDOWS:
      emsdk += '.bat'
    self.assertTrue(os.path.exists(emsdk))

    check_call([emsdk, 'install', 'latest'])
    check_call([emsdk, 'activate', 'latest'])

    # Check that emcc exists in the expected location
    emcc = upstream_emcc(longpath)
    print(emcc)
    self.assertTrue(os.path.exists(emcc))

    # Find the longest installed path and assert this is longer than 256
    longest_path = get_longest_path_in_dir(longpath)
    print(f'longest ({len(longest_path)}: {longest_path})')
    self.assertGreater(len(longest_path), 256)

    # Finally make sure we can actaully compile something
    check_call([emcc, 'hello_world.c'])

  def test_unknown_arch(self):
    env = os.environ.copy()
    env['EMSDK_ARCH'] = 'mips'
    failing_call_with_output(emsdk + ' install latest',
                             expected='unknown machine architecture: mips',
                             env=env)

  def test_wrong_bitness(self):
    env = os.environ.copy()
    env['EMSDK_ARCH'] = 'x86'
    failing_call_with_output(emsdk + ' install sdk-latest-64bit',
                             expected='is only provided for 64-bit OSe',
                             env=env)

  def test_already_installed(self):
    # Test we don't re-download unnecessarily
    checked_call_with_output(emsdk + ' install latest', expected='already installed', unexpected='Downloading:')

  def test_list(self):
    # Test we report installed tools properly. The latest version should be
    # installed, but not some random old one.
    checked_call_with_output(emsdk + ' list', expected=TAGS['aliases']['latest'] + '    INSTALLED', unexpected='1.39.15    INSTALLED:')

  def test_config_contents(self):
    print('test .emscripten contents')
    run_emsdk('install 6.0.3')
    run_emsdk('activate 6.0.3')
    with open(emconfig) as f:
      config = f.read()
    self.assertIn('upstream', config)

    # Older version of emscripten (prior to 6.0.3) don't support $CFGDIR
    self.assertIn('import os', config)
    self.assertIn('emsdk_path + ', config)
    self.assertNotIn('$CFGDIR', config)

    # For newer versions we use $CFGDIR
    version_file = os.path.join('upstream', 'emscripten', 'emscripten-version.txt')
    with open(version_file) as f:
      old_ver = f.read()
    try:
      # Hack the version file to contain 6.0.4
      with open(version_file, 'w') as f:
        f.write('6.0.4\n')
      # Re-activate 6.0.3 but with the hacked version file which makes it
      # appear to contain 6.0.4.
      run_emsdk('activate 6.0.3')
      with open(emconfig) as f:
        config = f.read()
      self.assertNotIn('import os', config)
      self.assertNotIn('emsdk_path', config)
      self.assertIn('$CFGDIR', config)
    finally:
      with open(version_file, 'w') as f:
        f.write(old_ver)
      run_emsdk('activate 6.0.3')

  def test_lib_building(self):
    print('building proper system libraries')
    do_lib_building(upstream_emcc())

  def test_redownload(self):
    print('go back to using upstream')
    run_emsdk('activate latest')

    # Test the normal tools like node don't re-download on re-install
    print('another install must re-download')
    checked_call_with_output(emsdk + ' uninstall node-24.19.0-64bit')
    checked_call_with_output(emsdk + ' install node-24.19.0-64bit', expected='Downloading:', unexpected='already installed')
    checked_call_with_output(emsdk + ' install node-24.19.0-64bit', unexpected='Downloading:', expected='already installed')

  def test_tot_upstream(self):
    print('test tot-upstream')
    run_emsdk('install tot-upstream')
    with open(emconfig) as f:
      config = f.read()
    run_emsdk('activate tot-upstream')
    self.addCleanup(remove_file, emconfig + '.old')
    with open(emconfig + '.old') as f:
      old_config = f.read()
    self.assertEqual(config, old_config)
    # TODO; test on latest as well
    check_call(upstream_emcc() + ' hello_world.c')

  def test_closure(self):
    # Specifically test with `--closure` so we know that node_modules is working
    check_call(upstream_emcc() + ' hello_world.c --closure=1')

  def test_specific_version(self):
    if MACOS_ARM64:
      self.skipTest('Old sdk versions do not have ARM64 binaries')
    print('test specific release (new, short name)')
    run_emsdk('install 1.38.33')
    print('another install, but no need for re-download')
    checked_call_with_output(emsdk + ' install 1.38.33', expected='Skipped', unexpected='Downloading:')
    run_emsdk('activate 1.38.33')

  def test_specific_version_full(self):
    if MACOS_ARM64:
      self.skipTest('Old sdk versions do not have ARM64 binaries')
    print('test specific release (new, full name)')
    run_emsdk('install sdk-1.38.33-64bit')
    run_emsdk('activate sdk-1.38.33-64bit')
    print('test specific release (new, tag name)')
    run_emsdk('install sdk-tag-1.38.33-64bit')
    run_emsdk('activate sdk-tag-1.38.33-64bit')

  def test_binaryen_from_source(self):
    if WINDOWS:
      # It takes over 30 mins to build binaryen using Visual Studio in CI
      self.skipTest('test is too slow under windows')
    run_emsdk(['install', '--build=Release', 'binaryen-main-64bit'])

  def test_no_32bit(self):
    print('test 32-bit error')
    emsdk_hacked = hack_emsdk('not is_os_64bit()', 'True')
    self.addCleanup(remove_file, emsdk_hacked)
    failing_call_with_output('%s %s install latest' % (sys.executable, emsdk_hacked),
                             'this tool is only provided for 64-bit OSes')

  def test_update_no_git(self):
    print('test non-git update')

    temp_dir = tempfile.mkdtemp()
    self.addCleanup(remove_tree, temp_dir)
    copy_emsdk_to(temp_dir)

    olddir = os.getcwd()
    try:
      os.chdir(temp_dir)
      run_emsdk('update')

      print('second time')
      run_emsdk('update')
    finally:
      os.chdir(olddir)

  def test_install_arbitrary(self):
    # Test that its possible to install arbrary emscripten-releases SDKs
    run_emsdk('install 1b7f7bc6002a3ca73647f41fc10e1fac7f06f804')

    # Check that its not re-downloaded
    checked_call_with_output(emsdk + ' install 1b7f7bc6002a3ca73647f41fc10e1fac7f06f804', expected='Skipped', unexpected='Downloading:')

  def test_install_tool(self):
    # Test that its possible to install emscripten as tool instead of SDK
    checked_call_with_output(emsdk + ' install releases-77b065ace39e6ab21446e13f92897f956c80476a', unexpected='Installing SDK')

  def test_activate_missing(self):
    run_emsdk('install latest')
    failing_call_with_output(emsdk + ' activate 2.0.1', expected="error: tool is not installed and therefore cannot be activated: 'releases-13e29bd55185e3c12802bc090b4507901856b2ba-64bit'")

  def test_keep_downloads(self):
    env = os.environ.copy()
    env['EMSDK_KEEP_DOWNLOADS'] = '1'
    # With EMSDK_KEEP_DOWNLOADS the downloading should happen on the first
    # install of 2.0.28, and again when we install 2.0.29, but not on the
    # second install of 2.0.28 because the zip should already be local.
    shutil.rmtree('downloads')
    checked_call_with_output(emsdk + ' install 3.1.54', expected='Downloading:', env=env)
    checked_call_with_output(emsdk + ' install 3.1.55', expected='Downloading:', env=env)
    checked_call_with_output(emsdk + ' install 3.1.54', expected='already downloaded, skipping', unexpected='Downloading:', env=env)


if __name__ == '__main__':
  unittest.main(verbosity=2)
