#!/usr/bin/env python3
import json
import os
import shutil
import subprocess
import sys
import tempfile

WINDOWS = sys.platform.startswith('win')
MACOS = sys.platform == 'darwin'

assert 'EM_CONFIG' in os.environ, "emsdk should be activated before running this script"

LIBC = os.environ['EM_CACHE'] + '/wasm/libc.a'

# Remove the EM_CACHE environment variable.  It interferes with testing since
# it would otherwise be fixed for the duration of the script and we expect
# "emsdk activate" to be able switch between SDKs during the running of this
# script.
del os.environ['EM_CACHE']

emconfig = os.environ['EM_CONFIG']
upstream_emcc = os.path.join('upstream', 'emscripten', 'emcc')
fastcomp_emcc = os.path.join('fastcomp', 'emscripten', 'emcc')
emsdk = './emsdk'
if WINDOWS:
  upstream_emcc += '.bat'
  fastcomp_emcc += '.bat'
  emsdk = 'emsdk.bat'
else:
  emsdk = './emsdk'

# Utilities


def listify(x):
  if type(x) == list or type(x) == tuple:
    return x
  return [x]


def check_call(cmd, **args):
  if type(cmd) != list:
    cmd = cmd.split()
  print('running: %s' % cmd)
  args['universal_newlines'] = True
  subprocess.check_call(cmd, **args)


def checked_call_with_output(cmd, expected=None, unexpected=None, stderr=None):
  cmd = cmd.split(' ')
  print('running: %s' % cmd)
  stdout = subprocess.check_output(cmd, stderr=stderr, universal_newlines=True)
  if expected:
    for x in listify(expected):
      assert x in stdout, 'call had the right output: ' + stdout + '\n[[[' + x + ']]]'
  if unexpected:
    for x in listify(unexpected):
      assert x not in stdout, 'call had the wrong output: ' + stdout + '\n[[[' + x + ']]]'


def failing_call_with_output(cmd, expected):
  proc = subprocess.Popen(cmd.split(' '), stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
  stdout, stderr = proc.communicate()
  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 right output'


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


# Set up

open('hello_world.c', 'w').write('''\
#include <stdio.h>

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

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

# Tests

print('test .emscripten contents (latest was installed/activated in test.sh)')
assert 'fastcomp' not in open(emconfig).read()
assert 'upstream' in open(emconfig).read()

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

# 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['latest'] + '    INSTALLED', unexpected='1.39.15    INSTALLED:')

print('building proper system libraries')


def test_lib_building(emcc, use_asmjs_optimizer):
  cache_building_messages = ['generating system library: ']

  def test_build(args, expected):
    if expected:
      expected = cache_building_messages
      unexpected = []
    else:
      expected = []
      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.
  test_build('', expected=False)
  check_call(emcc + ' --clear-cache')
  test_build(' -O2', expected=True)
  test_build(' -s WASM=0', expected=False)
  test_build(' -O2 -s WASM=0', expected=False)


def run_emsdk(cmd):
  if type(cmd) != list:
    cmd = cmd.split()
  check_call([emsdk] + cmd)


test_lib_building(upstream_emcc, use_asmjs_optimizer=True)

print('update')
run_emsdk('update-tags')

print('test the last fastcomp release')
run_emsdk('install 1.40.1-fastcomp')
run_emsdk('activate 1.40.1-fastcomp')

test_lib_building(fastcomp_emcc, use_asmjs_optimizer=False)
assert open(emconfig).read().count('LLVM_ROOT') == 1
assert 'upstream' not in open(emconfig).read()
assert 'fastcomp' in open(emconfig).read()

print('verify latest fastcomp version is fixed at 1.40.1')
checked_call_with_output(fastcomp_emcc + ' -v', '1.40.1', stderr=subprocess.STDOUT)

print('verify that attempting to use newer fastcomp gives an error')
fastcomp_error = 'The fastcomp backend is not getting new builds or releases. Please use the upstream llvm backend or use an older version than 2.0.0 (such as 1.40.1).'
failing_call_with_output(emsdk + ' install latest-fastcomp', fastcomp_error)
failing_call_with_output(emsdk + ' install tot-fastcomp', fastcomp_error)
failing_call_with_output(emsdk + ' install 2.0.0-fastcomp', fastcomp_error)

print('go back to using upstream')
run_emsdk('activate latest')

print('clear cache')
check_call(upstream_emcc + ' --clear-cache')
assert not os.path.exists(LIBC)

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

print('test tot-upstream')
run_emsdk('install tot-upstream')
old_config = open(emconfig).read()
run_emsdk('activate tot-upstream')
assert old_config == open(emconfig + '.old').read()
# TODO; test on latest as well
check_call(upstream_emcc + ' hello_world.c')

print('test specific release (old, using sdk-* notation)')
run_emsdk('install sdk-fastcomp-1.38.31-64bit')
run_emsdk('activate sdk-fastcomp-1.38.31-64bit')

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')
assert 'upstream' not in open(emconfig).read()
assert 'fastcomp' in open(emconfig).read()

print('test specific release (new, full name)')
run_emsdk('install sdk-1.38.33-upstream-64bit')
run_emsdk('activate sdk-1.38.33-upstream-64bit')

print('test specific release (new, full name)')
run_emsdk('install sdk-tag-1.38.33-64bit')
run_emsdk('activate sdk-tag-1.38.33-64bit')

print('test binaryen source build')
run_emsdk(['install', '--build=Release', '--generator=Unix Makefiles', 'binaryen-master-64bit'])

print('test 32-bit error')

failing_call_with_output('python %s install latest' % hack_emsdk('not is_os_64bit()', 'True'), 'this tool is only provided for 64-bit OSes')

print('test non-git update')

temp_dir = tempfile.mkdtemp()

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

os.chdir(temp_dir)

run_emsdk('update')
print('second time')
run_emsdk('update')

print('verify downloads exist for all OSes')
latest_hash = TAGS['releases'][TAGS['latest']]
for osname, suffix in [
  ('linux', 'tbz2'),
  ('mac', 'tbz2'),
  ('win', 'zip')
]:
  url = 'https://storage.googleapis.com/webassembly/emscripten-releases-builds/%s/%s/wasm-binaries.%s' % (osname, latest_hash, suffix)
  print('  checking url: ' + url),
  check_call('curl --fail --head --silent ' + url, stdout=subprocess.PIPE)
