#!/usr/bin/env python3
import json
import os
import platform
import shutil
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


# 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):
  @classmethod
  def setUpClass(cls):
    with open('hello_world.c', 'w') as f:
      f.write('''\
#include <stdio.h>

int main() {
   printf("Hello, world!\\n");
   return 0;
}
''')

  def setUp(self):
    run_emsdk('install latest')
    run_emsdk('activate latest')

  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
    if os.path.exists(longpath):
      # shutil.rmtree requires the special long path prefix
      longpath_with_prefix = '\\\\?\\' + longpath
      assert os.path.exists(longpath_with_prefix)
      shutil.rmtree(longpath_with_prefix)

    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-22.16.0-64bit')
    checked_call_with_output(emsdk + ' install node-22.16.0-64bit', expected='Downloading:', unexpected='already installed')
    checked_call_with_output(emsdk + ' install node-22.16.0-64bit', unexpected='Downloading:', expected='already installed')

  def test_tot_upstream(self):
    print('test update-tags')
    run_emsdk('update-tags')
    print('test tot-upstream')
    run_emsdk('install tot-upstream')
    with open(emconfig) as f:
      config = f.read()
    run_emsdk('activate tot-upstream')
    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')
    failing_call_with_output('%s %s install latest' % (sys.executable, emsdk_hacked),
                             'this tool is only provided for 64-bit OSes')
    os.remove(emsdk_hacked)

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

    temp_dir = tempfile.mkdtemp()
    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)
