#!/usr/bin/env python
"""wrapper around emcc link step.

This wrapper currently serves the following purposes.

1. When building with --config=wasm the final output is multiple files, usually
   at least one .js and one .wasm file. Since the cc_binary link step only
   allows a single output, we must tar up the outputs into a single file.

2. Add quotes around arguments that need them in the response file to work
   around a bazel quirk.

3. Ensure the external_debug_info section of the wasm points at the correct
   bazel path.
"""

from __future__ import print_function

import argparse
import os
import subprocess
import sys

# Only argument should be @path/to/parameter/file
assert sys.argv[1][0] == '@', sys.argv
param_filename = sys.argv[1][1:]
param_file_args = [l.strip() for l in open(param_filename, 'r').readlines()]

# Re-write response file if needed.
if any(' ' in a for a in param_file_args):
  new_param_filename = param_filename + '.modified'
  with open(new_param_filename, 'w') as f:
    for param in param_file_args:
      if ' ' in param:
        f.write('"%s"' % param)
      else:
        f.write(param)
      f.write('\n')
  sys.argv[1] = '@' + new_param_filename

emcc_py = os.path.join(os.environ['EMSCRIPTEN'], 'emcc.py')
rtn = subprocess.call([sys.executable, emcc_py] + sys.argv[1:])
if rtn != 0:
  sys.exit(1)

# Parse the arguments that we gave to the linker to determine what the output
# file is named and what the output format is.
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument('-o')
parser.add_argument('--oformat')
options = parser.parse_known_args(param_file_args)[0]
output_file = options.o
oformat = options.oformat
outdir = os.path.normpath(os.path.dirname(output_file))
base_name = os.path.basename(output_file)

# The output file name is the name of the build rule that was built.
# Add an appropriate file extension based on --oformat.
if oformat is not None:
  base_name_split = os.path.splitext(base_name)

  # If the output name has no extension, give it the appropriate extension.
  if not base_name_split[1]:
    os.rename(output_file, output_file + '.' + oformat)

  # If the output name does have an extension and it matches the output format,
  # change the base_name so it doesn't have an extension.
  elif base_name_split[1] == '.' + oformat:
    base_name = base_name_split[0]

  # If the output name does have an extension and it does not match the output
  # format, change the base_name so it doesn't have an extension and rename
  # the output_file so it has the proper extension.
  # Note that if you do something like name your build rule "foo.js" and pass
  # "--oformat=html", emscripten will write to the same file for both the js and
  # html output, overwriting the js output entirely with the html.
  # Please don't do that.
  else:
    base_name = base_name_split[0]
    os.rename(output_file, os.path.join(outdir, base_name + '.' + oformat))

files = []
extensions = [
    '.js',
    '.wasm',
    '.wasm.map',
    '.js.mem',
    '.fetch.js',
    '.worker.js',
    '.data',
    '.js.symbols',
    '.wasm.debug.wasm',
    '.html'
]

for ext in extensions:
  filename = base_name + ext
  if os.path.exists(os.path.join(outdir, filename)):
    files.append(filename)

wasm_base = os.path.join(outdir, base_name + '.wasm')
if os.path.exists(wasm_base + '.debug.wasm') and os.path.exists(wasm_base):
  # If we have a .wasm.debug.wasm file and a .wasm file, we need to rewrite the
  # section in the .wasm file that refers to it. The path that's in there
  # is the blaze output path; we want it to be just the filename.

  llvm_objcopy = os.path.join(
      os.environ['EM_BIN_PATH'], 'bin/llvm-objcopy')
  # First, check to make sure the .wasm file has the header that needs to be
  # rewritten.
  rtn = subprocess.call([
      llvm_objcopy,
      '--dump-section=external_debug_info=/dev/null',
      wasm_base], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  if rtn == 0:
    # If llvm-objcopy did not return an error, the external_debug_info section
    # must exist, so we're good to continue.

    # Next we need to convert length of the filename to LEB128.
    # Start by converting the length of the filename to a bit string.
    bit_string = '{0:b}'.format(len(base_name + '.wasm.debug.wasm'))

    # Pad the bit string with 0s so that its length is a multiple of 7.
    while len(bit_string) % 7 != 0:
      bit_string = '0' + bit_string

    # Break up our bit string into chunks of 7.
    # We do this backwards because the final format is little-endian.
    final_bytes = bytearray()
    for i in reversed(range(0, len(bit_string), 7)):
      binary_part = bit_string[i:i + 7]
      if i != 0:
        # Every chunk except the last one needs to be prepended with '1'.
        # The length of each chunk is 7, so that one has an implicit '0'.
        binary_part = '1' + binary_part
      final_bytes.append(int(binary_part, 2))
    # Finally, add the actual filename.
    final_bytes.extend((base_name + '.wasm.debug.wasm').encode())

    # Write our length + filename bytes to a temp file.
    with open('debugsection.tmp', 'wb+') as f:
      f.write(final_bytes)
      f.close()

    # First delete the old section.
    subprocess.check_call([
        llvm_objcopy,
        wasm_base,
        '--remove-section=external_debug_info'])
    # Rewrite section with the new size and filename from the temp file.
    subprocess.check_call([
        llvm_objcopy,
        wasm_base,
        '--add-section=external_debug_info=debugsection.tmp'])

# Make sure we have at least one output file.
if not len(files):
  print('emcc.py did not appear to output any known files!')
  sys.exit(1)

# cc_binary must output exactly one file; put all the output files in a tarball.
cmd = ['tar', 'cf', 'tmp.tar'] + files
subprocess.check_call(cmd, cwd=outdir)
os.rename(os.path.join(outdir, 'tmp.tar'), output_file)

sys.exit(0)
