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

upstream_emcc = os.path.join('upstream', 'emscripten', 'emcc')
emsdk = './emsdk'
if WINDOWS:
  upstream_emcc += '.bat'
  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)


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 = os.path.join(longpath, 'upstream', 'emscripten', 'emcc')
    if WINDOWS:
      emcc += '.bat'
    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')
    with open(emconfig) as f:
      config = f.read()
    assert 'upstream' in config

  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 MACOS:
      self.skipTest("https://github.com/WebAssembly/binaryen/issues/4299")
    if WINDOWS:
      self.skipTest("https://github.com/emscripten-core/emsdk/issues/1624")
    print('test binaryen source build')
    run_emsdk(['install', '--build=Release', '--generator=Unix Makefiles', '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)
