#!/usr/bin/env python

import argparse
import os
import os.path
import shutil
import subprocess
import sys
import tempfile

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
REPO_ROOT_DIR = os.path.dirname(SCRIPT_DIR)
BIN_DIR = os.path.join(REPO_ROOT_DIR, 'bin')

CLANG = os.path.join(BIN_DIR, 'clang')
WACC = os.path.join(BIN_DIR, 'wacc')
LINKER = os.path.join(BIN_DIR, 's2wasm')
SEXPR_WASM = os.path.join(BIN_DIR, 'sexpr-wasm')
D8 = os.path.join(BIN_DIR, 'd8')
WASM_JS = os.path.join(REPO_ROOT_DIR, 'test', 'wasm.js')


class Error(Exception):
  pass


def call_and_suppress_stderr(cmd):
  process = subprocess.Popen(cmd,
                             stderr=subprocess.PIPE)
  _, stderr = process.communicate()
  if process.returncode != 0:
    raise Error(stderr)


def main(args):
  parser = argparse.ArgumentParser()
  parser.add_argument('in_file', help='input file (C or WAST)')
  parser.add_argument('--js-env', help='JS/WASM environment file')
  parser.add_argument('--native-env', help='native environment file')
  parser.add_argument('--dump', help='directory to store intermediate files')
  options = parser.parse_args(args)

  if not options.js_env and not options.native_env:
    options.js_env = WASM_JS

  path_parts = os.path.splitext(os.path.basename(options.in_file))
  basename = path_parts[0]
  extension = path_parts[1]
  if not options.dump:
    clean_temp_dir = True
    temp_dir = tempfile.mkdtemp(prefix='wasm-e2e-run-')
  else:
    clean_temp_dir = False
    temp_dir = options.dump
    if not os.path.exists(temp_dir):
      os.makedirs(temp_dir)

  try:
    if options.js_env:
      if extension == '.c':
        s_file = os.path.join(temp_dir, basename + '.s')
        wast_file = os.path.join(temp_dir, basename + '.wast')
        subprocess.check_call([WACC, '-fno-builtin', options.in_file, '-o', s_file, '-I', '.'])
        subprocess.check_call([LINKER, s_file, '-o', wast_file])
      elif extension == '.wast':
        wast_file = options.in_file
      else:
        raise Exception('unimplemented input file type: %s' % options.in_file)

      wasm_file = os.path.join(temp_dir, basename + '.wasm')

      subprocess.check_call([SEXPR_WASM, wast_file, '-o', wasm_file])
      call_and_suppress_stderr([D8, '--expose-wasm', options.js_env, '--', wasm_file])

    if options.native_env:
      executable_file = os.path.join(temp_dir, basename)
      subprocess.check_call([CLANG, '-O2', options.in_file, options.native_env,
                             '-o', executable_file, '-I', '.'])
      subprocess.check_call([executable_file])

  finally:
    if clean_temp_dir:
      shutil.rmtree(temp_dir)


if __name__ == '__main__':
  try:
    sys.exit(main(sys.argv[1:]))
  except (Error, OSError, subprocess.CalledProcessError) as e:
    sys.stderr.write(str(e) + '\n')
    sys.exit(1)
