#!/usr/bin/python
# Copyright 2013 The Emscripten Authors.  All rights reserved.
# Emscripten is available under two separate licenses, the MIT license and the
# University of Illinois/NCSA Open Source License.  Both these licenses can be
# found in the LICENSE file.

# This is a helper script to validate a file for asm.js.

# cmdline usage: 'python validate_asmjs.py filename.{html/js}'
# Prints a line starting with 'OK: ' on success, and returns process exit code 0.
# On failure, prints a line starting with 'FAIL: ', and returns a nonzero process exit code.

# python usage: 'validate_asmjs("filename.{html/js}", muteOutput=True/False)'
# Returns True/False depending on whether the file was valid asm.js.

# This script depends on the SpiderMonkey JS engine, which must be present in PATH in order for this script to function.

from __future__ import print_function
import os
import re
import subprocess
import sys
import tempfile

sys.path.insert(1, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from tools import shared


# Given a .js file, returns True/False depending on if that file is valid asm.js
def validate_asmjs_jsfile(filename, muteOutput):
  cmd = shared.SPIDERMONKEY_ENGINE + ['-c', filename]
  if not shared.SPIDERMONKEY_ENGINE or cmd[0] == 'js-not-found' or len(cmd[0].strip()) == 0:
    print('Could not find SpiderMonkey engine! Please set its location to SPIDERMONKEY_ENGINE in your ' + shared.hint_config_file_location() + ' configuration file!', file=sys.stderr)
    return False
  try:
    process = shared.run_process(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
  except Exception as e:
    print('Executing command ' + str(cmd) + ' failed due to an exception: ' + str(e) + '!', file=sys.stderr)
    return False
  stdout = process.stdout
  stderr = process.stderr
  if not muteOutput:
    if len(stdout.strip()):
      print(stdout.strip())
    if len(stderr.strip()):
      # Pretty-print the output not to contain a spurious warning.
      warning_re = re.compile(re.escape('warning: successfully compiled asm.js'), re.IGNORECASE)
      stderr = warning_re.sub(' successfully compiled asm.js', stderr)
      print(stderr.strip(), file=sys.stderr)
  if 'successfully compiled asm.js' in stderr.lower():
    return True
  else:
    return False


# This tool takes as input a file built with Emscripten (either .html or .js) and validates it for asm.js.
# Returns True/False denoting whether the file was valid asm.js. In case of a .html file, all <script>content</script> tags are searched,
# and the ones containing a "use asm" section are validated.
def validate_asmjs(filename, muteOutput):
  if filename.endswith('.html'):
    html = open(filename, 'r').read()
    matches = re.findall(r'''<\w*script\w*.*?>(.*?)<\w*/script\w*>''', html, re.DOTALL | re.MULTILINE)
    numAsmJsBlocks = 0
    for match in matches:
      if '"use asm"' in match:
        numAsmJsBlocks = numAsmJsBlocks + 1
        tmp_js = tempfile.mkstemp(suffix='.js')
        os.write(tmp_js[0], match)
        os.close(tmp_js[0])
        valid_asmjs = validate_asmjs_jsfile(tmp_js[1], muteOutput)
        os.remove(tmp_js[1])
        if not valid_asmjs:
          return False
    if numAsmJsBlocks == 0:
      # Test a .js file with the same basename - emcc convention
      # is to generate files with same basename but different suffix.
      js_file = filename.replace('.html', '.js')
      if os.path.isfile(js_file):
        return validate_asmjs(js_file, muteOutput)
      if not muteOutput:
        print('Error: the file does not contain any "use asm" modules.', file=sys.stderr)
      return False
    else:
      return True
  else:
    return validate_asmjs_jsfile(filename, muteOutput)


def main():
  if len(sys.argv) < 2:
    print('Usage: validate_asmjs <filename>')
    return 2
  if validate_asmjs(sys.argv[1], muteOutput=False):
    print("OK: File '" + sys.argv[1] + "' validates as asm.js")
    return 0
  else:
    print("FAIL: File '" + sys.argv[1] + "' is not valid asm.js")
    return 1


if __name__ == '__main__':
  sys.exit(main())
