# Copyright 2017 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

from __future__ import division
from __future__ import print_function

import array
import difflib
import distutils.dir_util
import filecmp
import io
import operator
import os
import posixpath
import re
import shutil
import struct
import subprocess
import sys
import tempfile
import uuid

from functools import reduce


def ZapTimestamp(filename):
  contents = open(filename, 'rb').read()
  # midl.exe writes timestamp 2147483647 (2^31 - 1) as creation date into its
  # outputs, but using the local timezone.  To make the output timezone-
  # independent, replace that date with a fixed string of the same length.
  # Also blank out the minor version number.
  if filename.endswith('.tlb'):
    # See https://chromium-review.googlesource.com/c/chromium/src/+/693223 for
    # a fairly complete description of the .tlb binary format.
    # TLB files start with a 54 byte header. Offset 0x20 stores how many types
    # are defined in the file, and the header is followed by that many uint32s.
    # After that, 15 section headers appear.  Each section header is 16 bytes,
    # starting with offset and length uint32s.
    # Section 12 in the file contains custom() data. custom() data has a type
    # (int, string, etc).  Each custom data chunk starts with a uint16_t
    # describing its type.  Type 8 is string data, consisting of a uint32_t
    # len, followed by that many data bytes, followed by 'W' bytes to pad to a
    # 4 byte boundary.  Type 0x13 is uint32 data, followed by 4 data bytes,
    # followed by two 'W' to pad to a 4 byte boundary.
    # The custom block always starts with one string containing "Created by
    # MIDL version 8...", followed by one uint32 containing 0x7fffffff,
    # followed by another uint32 containing the MIDL compiler version (e.g.
    # 0x0801026e for v8.1.622 -- 0x26e == 622).  These 3 fields take 0x54 bytes.
    # There might be more custom data after that, but these 3 blocks are always
    # there for file-level metadata.
    # All data is little-endian in the file.
    assert contents[0:8] == b'MSFT\x02\x00\x01\x00'
    ntypes, = struct.unpack_from('<I', contents, 0x20)
    custom_off, custom_len = struct.unpack_from(
        '<II', contents, 0x54 + 4*ntypes + 11*16)
    assert custom_len >= 0x54
    # First: Type string (0x8), followed by 0x3e characters.
    assert contents[custom_off:custom_off + 6] == b'\x08\x00\x3e\x00\x00\x00'
    assert re.match(
        br'Created by MIDL version 8\.\d\d\.\d{4} '
        br'at ... Jan 1. ..:..:.. 2038\n',
        contents[custom_off + 6:custom_off + 6 + 0x3e])
    # Second: Type uint32 (0x13) storing 0x7fffffff (followed by WW / 0x57 pad)
    assert contents[custom_off+6+0x3e:custom_off+6+0x3e+8] == \
        b'\x13\x00\xff\xff\xff\x7f\x57\x57'
    # Third: Type uint32 (0x13) storing MIDL compiler version.
    assert contents[custom_off + 6 + 0x3e + 8:custom_off + 6 + 0x3e + 8 +
                    2] == b'\x13\x00'
    # Replace "Created by" string with fixed string, and fixed MIDL version with
    # 8.1.622 always.
    contents = (
        contents[0:custom_off + 6] +
        b'Created by MIDL version 8.xx.xxxx at a redacted point in time\n' +
        # uint32 (0x13) val 0x7fffffff, WW, uint32 (0x13), val 0x0801026e, WW
        b'\x13\x00\xff\xff\xff\x7f\x57\x57\x13\x00\x6e\x02\x01\x08\x57\x57' +
        contents[custom_off + 0x54:])
  else:
    contents = re.sub(
        br'File created by MIDL compiler version 8\.\d\d\.\d{4} \*/\r\n'
        br'/\* at ... Jan 1. ..:..:.. 2038',
        br'File created by MIDL compiler version 8.xx.xxxx */\r\n'
        br'/* at a redacted point in time', contents)
    contents = re.sub(
        br'    Oicf, W1, Zp8, env=(.....) \(32b run\), '
        br'target_arch=(AMD64|X86) 8\.\d\d\.\d{4}',
        br'    Oicf, W1, Zp8, env=\1 (32b run), target_arch=\2 8.xx.xxxx',
        contents)
    # TODO(thakis): If we need more hacks than these, try to verify checked-in
    # outputs when we're using the hermetic toolchain.
    # midl.exe older than 8.1.622 omit '//' after #endif, fix that:
    contents = contents.replace(b'#endif !_MIDL_USE_GUIDDEF_',
                                b'#endif // !_MIDL_USE_GUIDDEF_')
    # midl.exe puts the midl version into code in one place.  To have
    # predictable output, lie about the midl version if it's not 8.1.622.
    # This is unfortunate, but remember that there's beauty too in imperfection.
    contents = contents.replace(b'0x801026c, /* MIDL Version 8.1.620 */',
                                b'0x801026e, /* MIDL Version 8.1.622 */')
  open(filename, 'wb').write(contents)


def get_tlb_contents(tlb_file):
  # See ZapTimestamp() for a short overview of the .tlb format.
  contents = open(tlb_file, 'rb').read()
  assert contents[0:8] == b'MSFT\x02\x00\x01\x00'
  ntypes, = struct.unpack_from('<I', contents, 0x20)
  type_off, type_len = struct.unpack_from('<II', contents, 0x54 + 4*ntypes)

  guid_off, guid_len = struct.unpack_from(
      '<II', contents, 0x54 + 4*ntypes + 5*16)
  assert guid_len % 24 == 0

  contents = array.array('B', contents)

  return contents, ntypes, type_off, guid_off, guid_len


def recreate_guid_hashtable(contents, ntypes, guid_off, guid_len):
  # This function is called after changing guids in section 6 (the "guid"
  # section). This function recreates the GUID hashtable in section 5. Since the
  # hash table uses chaining, it's easiest to recompute it from scratch rather
  # than trying to patch it up.
  hashtab = [0xffffffff] * (0x80 // 4)
  for guidind in range(guid_off, guid_off + guid_len, 24):
    guidbytes, typeoff, nextguid = struct.unpack_from(
        '<16sII', contents, guidind)
    words = struct.unpack('<8H', guidbytes)
    # midl seems to use the following simple hash function for GUIDs:
    guidhash = reduce(operator.xor, [w for w in words]) % (0x80 // 4)
    nextguid = hashtab[guidhash]
    struct.pack_into('<I', contents, guidind + 0x14, nextguid)
    hashtab[guidhash] = guidind - guid_off
  hash_off, hash_len = struct.unpack_from(
      '<II', contents, 0x54 + 4*ntypes + 4*16)
  for i, hashval in enumerate(hashtab):
    struct.pack_into('<I', contents, hash_off + 4*i, hashval)


def overwrite_guids_h(h_file, dynamic_guids):
  contents = open(h_file, 'rb').read()
  for key in dynamic_guids:
    contents = re.sub(key, dynamic_guids[key], contents, flags=re.I)
  open(h_file, 'wb').write(contents)


def get_uuid_format(guid, prefix):
  formatted_uuid = '0x%s,0x%s,0x%s,' % (guid[0:8], guid[9:13], guid[14:18])
  formatted_uuid += '%s0x%s,0x%s' % (prefix, guid[19:21], guid[21:23])
  for i in range(24, len(guid), 2):
    formatted_uuid += ',0x' + guid[i:i + 2]
  return formatted_uuid


def get_uuid_format_iid_file(guid):
  # Convert from "D0E1CACC-C63C-4192-94AB-BF8EAD0E3B83" to
  # 0xD0E1CACC,0xC63C,0x4192,0x94,0xAB,0xBF,0x8E,0xAD,0x0E,0x3B,0x83.
  return get_uuid_format(guid, '')


def overwrite_guids_iid(iid_file, dynamic_guids):
  contents = open(iid_file, 'rb').read()
  for key in dynamic_guids:
    contents = re.sub(get_uuid_format_iid_file(key),
                      get_uuid_format_iid_file(dynamic_guids[key]),
                      contents,
                      flags=re.I)
  open(iid_file, 'wb').write(contents)


def get_uuid_format_proxy_file(guid):
  # Convert from "D0E1CACC-C63C-4192-94AB-BF8EAD0E3B83" to
  # {0xD0E1CACC,0xC63C,0x4192,{0x94,0xAB,0xBF,0x8E,0xAD,0x0E,0x3B,0x83}}.
  return get_uuid_format(guid, '{')


def overwrite_guids_proxy(proxy_file, dynamic_guids):
  contents = open(proxy_file, 'rb').read()
  for key in dynamic_guids:
    contents = re.sub(get_uuid_format_proxy_file(key),
                      get_uuid_format_proxy_file(dynamic_guids[key]),
                      contents,
                      flags=re.I)
  open(proxy_file, 'wb').write(contents)


def getguid(contents, offset):
  # Returns a guid string of the form "D0E1CACC-C63C-4192-94AB-BF8EAD0E3B83".
  g0, g1, g2, g3 = struct.unpack_from('<IHH8s', contents, offset)
  g3 = ''.join(['%02X' % ord(g) for g in g3])
  return '%08X-%04X-%04X-%s-%s' % (g0, g1, g2, g3[0:4], g3[4:])


def setguid(contents, offset, guid):
  guid = uuid.UUID(guid)
  struct.pack_into('<IHH8s', contents, offset,
                   *(guid.fields[0:3] + (guid.bytes[8:], )))


def overwrite_guids_tlb(tlb_file, dynamic_guids):
  contents, ntypes, type_off, guid_off, guid_len = get_tlb_contents(tlb_file)

  for i in range(0, guid_len, 24):
    current_guid = getguid(contents, guid_off + i)
    for key in dynamic_guids:
      if key.lower() == current_guid.lower():
        setguid(contents, guid_off + i, dynamic_guids[key])

  recreate_guid_hashtable(contents, ntypes, guid_off, guid_len)
  open(tlb_file, 'wb').write(contents)


# Handle multiple guid substitutions, where |dynamic_guids| is of the form
# "PLACEHOLDER-GUID-158428a4-6014-4978-83ba-9fad0dabe791="
# "3d852661-c795-4d20-9b95-5561e9a1d2d9,"
# "PLACEHOLDER-GUID-63B8FFB1-5314-48C9-9C57-93EC8BC6184B="
# "D0E1CACC-C63C-4192-94AB-BF8EAD0E3B83".
#
# Before specifying |dynamic_guids| in the build, the IDL file is first compiled
# with "158428a4-6014-4978-83ba-9fad0dabe791" and
# "63B8FFB1-5314-48C9-9C57-93EC8BC6184B". These are the "replaceable" guids,
# i.e., guids that can be replaced in future builds. The resulting MIDL outputs
# are copied over to src\third_party\win_build_output\.
#
# Then, in the future, any changes to these guids can be accomplished by
# providing |dynamic_guids| of the format above in the build file. These
# "dynamic" guid changes by themselves will not require the MIDL compiler and
# therefore will not require copying output over to
# src\third_party\win_build_output\.
#
# The pre-generated src\third_party\win_build_output\ files are used for
# cross-compiling on other platforms, since the MIDL compiler is Windows-only.
def overwrite_guids(h_file, iid_file, proxy_file, tlb_file, dynamic_guids):
  # Fix up GUIDs in .h, _i.c, _p.c, and .tlb.
  overwrite_guids_h(h_file, dynamic_guids)
  overwrite_guids_iid(iid_file, dynamic_guids)
  overwrite_guids_proxy(proxy_file, dynamic_guids)
  if tlb_file:
    overwrite_guids_tlb(tlb_file, dynamic_guids)


# This function removes all occurrences of 'PLACEHOLDER-GUID-' from the
# template, and if |dynamic_guids| is specified, also replaces the guids within
# the file. Finally, it writes the resultant output to the |idl| file.
def generate_idl_from_template(idl_template, dynamic_guids, idl):
  contents = open(idl_template, 'rb').read()
  contents = re.sub('PLACEHOLDER-GUID-', '', contents, flags=re.I)
  if dynamic_guids:
    for key in dynamic_guids:
      contents = re.sub(key, dynamic_guids[key], contents, flags=re.I)
  open(idl, 'wb').write(contents)


# This function runs the MIDL compiler with the provided arguments. It creates
# and returns a tuple of |0,midl_output_dir| on success.
def run_midl(args, env_dict):
  midl_output_dir = tempfile.mkdtemp()
  delete_midl_output_dir = True

  try:
    popen = subprocess.Popen(args + ['/out', midl_output_dir],
                             shell=True,
                             env=env_dict,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.STDOUT)
    out, _ = popen.communicate()
    if popen.returncode != 0:
      return popen.returncode, midl_output_dir

    # Filter junk out of stdout, and write filtered versions. Output we want
    # to filter is pairs of lines that look like this:
    # Processing C:\Program Files (x86)\Microsoft SDKs\...\include\objidl.idl
    # objidl.idl
    lines = out.decode('utf-8').splitlines()
    prefixes = ('Processing ', '64 bit Processing ')
    processing = set(
        os.path.basename(x) for x in lines if x.startswith(prefixes))
    for line in lines:
      if not line.startswith(prefixes) and line not in processing:
        print(line)

    for f in os.listdir(midl_output_dir):
      ZapTimestamp(os.path.join(midl_output_dir, f))

    delete_midl_output_dir = False
  finally:
    if os.path.exists(midl_output_dir) and delete_midl_output_dir:
      shutil.rmtree(midl_output_dir)

  return 0, midl_output_dir


# This function adds support for dynamic generation of guids: when values are
# specified as 'uuid5:name', this function will substitute the values with
# generated dynamic guids using the uuid5 function. The uuid5 function generates
# a guid based on the SHA-1 hash of a namespace identifier (which is the guid
# that comes after 'PLACEHOLDER-GUID-') and a name (which is a string, such as a
# version string "87.1.2.3").
#
# For instance, when |dynamic_guid| is of the form:
# "PLACEHOLDER-GUID-158428a4-6014-4978-83ba-9fad0dabe791=uuid5:88.0.4307.0
# ,"
# "PLACEHOLDER-GUID-63B8FFB1-5314-48C9-9C57-93EC8BC6184B=uuid5:88.0.4307.0
# "
#
# "PLACEHOLDER-GUID-158428a4-6014-4978-83ba-9fad0dabe791" would be substituted
# with uuid5("158428a4-6014-4978-83ba-9fad0dabe791", "88.0.4307.0"), which is
# "64700170-AD80-5DE3-924E-2F39D862CFD5". And
# "PLACEHOLDER-GUID-63B8FFB1-5314-48C9-9C57-93EC8BC6184B" would be
# substituted with uuid5("63B8FFB1-5314-48C9-9C57-93EC8BC6184B", "88.0.4307.0"),
# which is "7B6E7538-3C38-5565-BC92-42BCEE268D76".
def uuid5_substitutions(dynamic_guids):
  for key, value in dynamic_guids.items():
    if value.startswith("uuid5:"):
      name = value.split("uuid5:", 1)[1]
      assert name
      dynamic_guids[key] = str(uuid.uuid5(uuid.UUID(key), name)).upper()


def main(arch, gendir, outdir, dynamic_guids, tlb, h, dlldata, iid, proxy,
         clang, idl, *flags):
  # Copy checked-in outputs to final location.
  source = gendir
  if os.path.isdir(os.path.join(source, os.path.basename(idl))):
    source = os.path.join(source, os.path.basename(idl))
  source = os.path.join(source, arch.split('.')[1])  # Append 'x86' or 'x64'.
  source = os.path.normpath(source)

  source_exists = True
  if not os.path.isdir(source):
    source_exists = False
    if sys.platform != 'win32':
      print('Directory %s needs to be populated from Windows first' % source)
      return 1

    # This is a brand new IDL file that does not have outputs under
    # third_party\win_build_output\midl. We create an empty directory for now.
    os.makedirs(source)

  common_files = [h, iid]
  if tlb != 'none':
    # Not all projects use tlb files.
    common_files += [tlb]
  else:
    tlb = None

  if dlldata != 'none':
    # Not all projects use dlldta files.
    common_files += [dlldata]
  else:
    dlldata = None

  # Not all projects use proxy files
  if proxy != 'none':
    # Not all projects use proxy files.
    common_files += [proxy]
  else:
    proxy = None

  for source_file in common_files:
    file_path = os.path.join(source, source_file)
    if not os.path.isfile(file_path):
      source_exists = False
      if sys.platform != 'win32':
        print('File %s needs to be generated from Windows first' % file_path)
        return 1

      # Either this is a brand new IDL file that does not have outputs under
      # third_party\win_build_output\midl or the file is (unexpectedly) missing.
      # We create an empty file for now. The rest of the machinery below will
      # then generate the correctly populated file using the MIDL compiler and
      # instruct the developer to copy that file under
      # third_party\win_build_output\midl.
      open(file_path, 'wb').close()
    shutil.copy(file_path, outdir)

  if dynamic_guids != 'none':
    assert '=' in dynamic_guids
    if dynamic_guids.startswith("ignore_proxy_stub,"):
      # TODO(ganesh): The custom proxy/stub file ("_p.c") is not generated
      # correctly for dynamic IIDs (but correctly if there are only dynamic
      # CLSIDs). The proxy/stub lookup functions generated by MIDL.exe within
      # "_p.c" rely on a sorted set of vtable lists, which we are not currently
      # regenerating. At the moment, no project in Chromium that uses dynamic
      # IIDs is relying on the custom proxy/stub file. So for now, if
      # |dynamic_guids| is prefixed with "ignore_proxy_stub,", we exclude the
      # custom proxy/stub file from the directory comparisons.
      common_files.remove(proxy)
      dynamic_guids = dynamic_guids.split("ignore_proxy_stub,", 1)[1]
    dynamic_guids = re.sub('PLACEHOLDER-GUID-', '', dynamic_guids, flags=re.I)
    dynamic_guids = dynamic_guids.split(',')
    dynamic_guids = dict(s.split('=') for s in dynamic_guids)
    uuid5_substitutions(dynamic_guids)
    if source_exists:
      overwrite_guids(*(os.path.join(outdir, file) if file else None
                        for file in [h, iid, proxy, tlb]),
                      dynamic_guids=dynamic_guids)
  else:
    dynamic_guids = None

  # On non-Windows, that's all we can do.
  if sys.platform != 'win32':
    return 0

  idl_template = None
  if dynamic_guids:
    idl_template = idl

    # posixpath is used here to keep the MIDL-generated files with a uniform
    # separator of '/' instead of mixed '/' and '\\'.
    idl = posixpath.join(
        outdir,
        os.path.splitext(os.path.basename(idl_template))[0] + '.idl')

    # |idl_template| can contain one or more occurrences of guids that are
    # substituted with |dynamic_guids|, and then MIDL is run on the substituted
    # IDL file.
    generate_idl_from_template(idl_template, dynamic_guids, idl)

  # On Windows, run midl.exe on the input and check that its outputs are
  # identical to the checked-in outputs (after replacing guids if
  # |dynamic_guids| is specified).

  # Read the environment block from the file. This is stored in the format used
  # by CreateProcess. Drop last 2 NULs, one for list terminator, one for
  # trailing vs. separator.
  env_pairs = open(arch).read()[:-2].split('\0')
  env_dict = dict([item.split('=', 1) for item in env_pairs])

  # Extract the /D options and send them to the preprocessor.
  preprocessor_options = '-E -nologo -Wno-nonportable-include-path'
  preprocessor_options += ''.join(
      [' ' + flag for flag in flags if flag.startswith('/D')])
  args = ['midl', '/nologo'] + list(flags) + (['/tlb', tlb] if tlb else []) + [
      '/h', h
  ] + (['/dlldata', dlldata] if dlldata else []) + ['/iid', iid] + (
      ['/proxy', proxy] if proxy else
      []) + ['/cpp_cmd', clang, '/cpp_opt', preprocessor_options, idl]

  returncode, midl_output_dir = run_midl(args, env_dict)
  if returncode != 0:
    return returncode

  # Now compare the output in midl_output_dir to the copied-over outputs.
  _, mismatch, errors = filecmp.cmpfiles(midl_output_dir, outdir, common_files)
  assert not errors

  if mismatch:
    print('midl.exe output different from files in %s, see %s' %
          (outdir, midl_output_dir))
    for f in mismatch:
      if f.endswith('.tlb'): continue
      fromfile = os.path.join(outdir, f)
      tofile = os.path.join(midl_output_dir, f)
      print(''.join(
          difflib.unified_diff(
              io.open(fromfile).readlines(),
              io.open(tofile).readlines(), fromfile, tofile)))

    if dynamic_guids:
      # |idl_template| can contain one or more occurrences of guids prefixed
      # with 'PLACEHOLDER-GUID-'. We first remove the extraneous
      # 'PLACEHOLDER-GUID-' prefix and then run MIDL on the substituted IDL
      # file.
      # No guid substitutions are done at this point, because we want to compile
      # with the placeholder guids and then instruct the user to copy the output
      # over to |source| which is typically src\third_party\win_build_output\.
      # In future runs, the placeholder guids in |source| are replaced with the
      # guids specified in |dynamic_guids|.
      generate_idl_from_template(idl_template, None, idl)
      returncode, midl_output_dir = run_midl(args, env_dict)
      if returncode != 0:
        return returncode

    print('To rebaseline:')
    print(r'  copy /y %s\* %s' % (midl_output_dir, source))
    return 1

  return 0


if __name__ == '__main__':
  sys.exit(main(*sys.argv[1:]))
