# Copyright 2014 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 a system-installed copy of the toolchain, packages all the required bits
into a .zip file.

It assumes default install locations for tools, on the C: drive.

1. Start from a fresh Windows VM image.
2. Download the VS installer. Run the installer with these parameters:
    --add Microsoft.VisualStudio.Workload.NativeDesktop
    --add Microsoft.VisualStudio.Component.VC.ATLMFC
    --add Microsoft.VisualStudio.Component.VC.Tools.ARM64
    --add Microsoft.VisualStudio.Component.VC.MFC.ARM64
    --includeRecommended --passive
These are equivalent to selecting the Desktop development with C++ workload,
within that the Visual C++ MFC for x86 and x64 component, and then  Individual
Components-> Compilers, build tools, and runtimes-> Visual C++ compilers and
libraries for ARM64, and Individual Components-> SDKs, libraries, and
frameworks-> Visual C++ MFC for ARM64 (which also brings in ATL for ARM64).
3. Use Add or Remove Programs to find the Windows SDK installed with VS
and modify it to include the debuggers.
4. Run this script, which will build a <sha1>.zip, something like this:
  python package_from_installed.py 2017|2019 -w 10.0.17763.0|<SDK version>

Express is not yet supported by this script, but patches welcome (it's not too
useful as the resulting zip can't be redistributed, and most will presumably
have a Pro license anyway).
"""

from __future__ import print_function

import collections
import glob
import json
import optparse
import os
import platform
import shutil
import subprocess
import sys
import tempfile
import zipfile

import get_toolchain_if_necessary


VS_VERSION = None
WIN_VERSION = None
VC_TOOLS = None
SUPPORTED_VS_VERSIONS = ['2017', '2019']


def GetVSPath():
  # Use vswhere to find the VS installation. This will find prerelease
  # versions because -prerelease is specified. This assumes that only one
  # version is installed.
  command = (r'C:\Program Files (x86)\Microsoft Visual Studio\Installer'
             r'\vswhere.exe -prerelease')
  marker = 'installationPath: '
  output = subprocess.check_output(command, universal_newlines=True)
  for line in output.splitlines():
    if line.startswith(marker):
      return line[len(marker):]
  raise Exception('VS %s path not found in vswhere output' % (VS_VERSION))


def ExpandWildcards(root, sub_dir):
  # normpath is needed to change '/' to '\\' characters.
  path = os.path.normpath(os.path.join(root, sub_dir))
  matches = glob.glob(path)
  if len(matches) != 1:
    raise Exception('%s had %d matches - should be one' % (path, len(matches)))
  return matches[0]


def BuildRepackageFileList(src_dir):
  # Strip off a trailing slash if present
  if src_dir.endswith('\\'):
    src_dir = src_dir[:-1]

  # Ensure .\Windows Kits\10\Debuggers exists and fail to repackage if it
  # doesn't.
  debuggers_path = os.path.join(src_dir, 'Windows Kits', '10', 'Debuggers')
  if not os.path.exists(debuggers_path):
    raise Exception('Repacking failed. Missing %s.' % (debuggers_path))

  result = []
  for root, _, files in os.walk(src_dir):
    for f in files:
      final_from = os.path.normpath(os.path.join(root, f))
      dest = final_from[len(src_dir) + 1:]
      result.append((final_from, dest))
  return result


def BuildFileList(override_dir, include_arm):
  result = []

  # Subset of VS corresponding roughly to VC.
  paths = [
      'DIA SDK/bin',
      'DIA SDK/idl',
      'DIA SDK/include',
      'DIA SDK/lib',
      VC_TOOLS + '/atlmfc',
      VC_TOOLS + '/crt',
      'VC/redist',
  ]

  if override_dir:
    paths += [
        (os.path.join(override_dir, 'bin'), VC_TOOLS + '/bin'),
        (os.path.join(override_dir, 'include'), VC_TOOLS + '/include'),
        (os.path.join(override_dir, 'lib'), VC_TOOLS + '/lib'),
    ]
  else:
    paths += [
        VC_TOOLS + '/bin',
        VC_TOOLS + '/include',
        VC_TOOLS + '/lib',
    ]

  paths += [
      ('VC/redist/MSVC/14.*.*/x86/Microsoft.VC*.CRT', 'sys32'),
      ('VC/redist/MSVC/14.*.*/x86/Microsoft.VC*.CRT',
       'Windows Kits/10//bin/x86'),
      ('VC/redist/MSVC/14.*.*/debug_nonredist/x86/Microsoft.VC*.DebugCRT',
       'sys32'),
      ('VC/redist/MSVC/14.*.*/x64/Microsoft.VC*.CRT', 'sys64'),
      ('VC/redist/MSVC/14.*.*/x64/Microsoft.VC*.CRT', 'VC/bin/amd64_x86'),
      ('VC/redist/MSVC/14.*.*/x64/Microsoft.VC*.CRT', 'VC/bin/amd64'),
      ('VC/redist/MSVC/14.*.*/x64/Microsoft.VC*.CRT',
       'Windows Kits/10/bin/x64'),
      ('VC/redist/MSVC/14.*.*/debug_nonredist/x64/Microsoft.VC*.DebugCRT',
       'sys64'),
  ]
  if include_arm:
    paths += [
        ('VC/redist/MSVC/14.*.*/arm64/Microsoft.VC*.CRT', 'sysarm64'),
        ('VC/redist/MSVC/14.*.*/arm64/Microsoft.VC*.CRT', 'VC/bin/amd64_arm64'),
        ('VC/redist/MSVC/14.*.*/arm64/Microsoft.VC*.CRT', 'VC/bin/arm64'),
        ('VC/redist/MSVC/14.*.*/arm64/Microsoft.VC*.CRT',
         'Windows Kits/10/bin/arm64'),
        ('VC/redist/MSVC/14.*.*/debug_nonredist/arm64/Microsoft.VC*.DebugCRT',
         'sysarm64'),
    ]

  vs_path = GetVSPath()

  for path in paths:
    src = path[0] if isinstance(path, tuple) else path
    # Note that vs_path is ignored if src is an absolute path.
    combined = ExpandWildcards(vs_path, src)
    if not os.path.exists(combined):
      raise Exception('%s missing.' % combined)
    if not os.path.isdir(combined):
      raise Exception('%s not a directory.' % combined)
    for root, _, files in os.walk(combined):
      for f in files:
        # vctip.exe doesn't shutdown, leaving locks on directories. It's
        # optional so let's avoid this problem by not packaging it.
        # https://crbug.com/735226
        if f.lower() =='vctip.exe':
          continue
        final_from = os.path.normpath(os.path.join(root, f))
        if isinstance(path, tuple):
          assert final_from.startswith(combined)
          dest = final_from[len(combined) + 1:]
          result.append(
              (final_from, os.path.normpath(os.path.join(path[1], dest))))
        else:
          assert final_from.startswith(vs_path)
          dest = final_from[len(vs_path) + 1:]
          result.append((final_from, dest))

  sdk_path = r'C:\Program Files (x86)\Windows Kits\10'
  debuggers_path = os.path.join(sdk_path, 'Debuggers')
  if not os.path.exists(debuggers_path):
    raise Exception('Packaging failed. Missing %s.' % (debuggers_path))

  for root, _, files in os.walk(sdk_path):
    for f in files:
      combined = os.path.normpath(os.path.join(root, f))
      # Some of the files in this directory are exceedingly long (and exceed
      # _MAX_PATH for any moderately long root), so exclude them. We don't need
      # them anyway. Exclude/filter/skip others just to save space.
      tail = combined[len(sdk_path) + 1:]
      skip_dir = False
      for dir in ['References\\', 'Windows Performance Toolkit\\', 'Testing\\',
                  'App Certification Kit\\', 'Extension SDKs\\',
                  'Assessment and Deployment Kit\\']:
        if tail.startswith(dir):
          skip_dir = True
      if skip_dir:
        continue
      # There may be many Include\Lib\Source\bin directories for many different
      # versions of Windows and packaging them all wastes ~450 MB
      # (uncompressed) per version and wastes time. Only copy the specified
      # version. Note that the SDK version number started being part of the bin
      # path with 10.0.15063.0.
      if (tail.startswith('Include\\') or tail.startswith('Lib\\') or
          tail.startswith('Source\\') or tail.startswith('bin\\')):
        if tail.count(WIN_VERSION) == 0:
          continue
      to = os.path.join('Windows Kits', '10', tail)
      result.append((combined, to))

  # Copy the x86 ucrt DLLs to all directories with x86 binaries that are
  # added to the path by SetEnv.cmd, and to sys32. Starting with the 17763
  # SDK the ucrt files are in WIN_VERSION\ucrt instead of just ucrt.
  ucrt_dir = os.path.join(sdk_path, 'redist', WIN_VERSION, r'ucrt\dlls\x86')
  if not os.path.exists(ucrt_dir):
    ucrt_dir = os.path.join(sdk_path, r'redist\ucrt\dlls\x86')
  ucrt_paths = glob.glob(ucrt_dir + r'\*')
  assert(len(ucrt_paths) > 0)
  for ucrt_path in ucrt_paths:
    ucrt_file = os.path.split(ucrt_path)[1]
    for dest_dir in [ r'Windows Kits\10\bin\x86', 'sys32' ]:
      result.append((ucrt_path, os.path.join(dest_dir, ucrt_file)))

  # Copy the x64 ucrt DLLs to all directories with x64 binaries that are
  # added to the path by SetEnv.cmd, and to sys64.
  ucrt_dir = os.path.join(sdk_path, 'redist', WIN_VERSION, r'ucrt\dlls\x64')
  if not os.path.exists(ucrt_dir):
    ucrt_dir = os.path.join(sdk_path, r'redist\ucrt\dlls\x64')
  ucrt_paths = glob.glob(ucrt_dir + r'\*')
  assert(len(ucrt_paths) > 0)
  for ucrt_path in ucrt_paths:
    ucrt_file = os.path.split(ucrt_path)[1]
    for dest_dir in [ r'VC\bin\amd64_x86', r'VC\bin\amd64',
                      r'Windows Kits\10\bin\x64', 'sys64']:
      result.append((ucrt_path, os.path.join(dest_dir, ucrt_file)))

  system_crt_files = [
      # Needed to let debug binaries run.
      'ucrtbased.dll',
  ]
  cpu_pairs = [
    ('x86', 'sys32'),
    ('x64', 'sys64'),
  ]
  if include_arm:
    cpu_pairs += [
      ('arm64', 'sysarm64'),
    ]
  for system_crt_file in system_crt_files:
    for cpu_pair in cpu_pairs:
      target_cpu, dest_dir = cpu_pair
      src_path = os.path.join(sdk_path, 'bin', WIN_VERSION, target_cpu, 'ucrt')
      result.append((os.path.join(src_path, system_crt_file),
                     os.path.join(dest_dir, system_crt_file)))

  # Generically drop all arm stuff that we don't need, and
  # drop .msi files because we don't need installers and drop
  # samples since those are not used by any tools.
  def is_skippable(f):
    return ('arm\\' in f.lower() or
            (not include_arm and 'arm64\\' in f.lower()) or
            'samples\\' in f.lower() or
            f.lower().endswith(('.msi',
                                '.msm')))
  return [(f, t) for f, t in result if not is_skippable(f)]

def GenerateSetEnvCmd(target_dir):
  """Generate a batch file that gyp expects to exist to set up the compiler
  environment.

  This is normally generated by a full install of the SDK, but we
  do it here manually since we do not do a full install."""
  vc_tools_parts = VC_TOOLS.split('/')

  # All these paths are relative to the root of the toolchain package.
  include_dirs = [
    ['Windows Kits', '10', 'Include', WIN_VERSION, 'um'],
    ['Windows Kits', '10', 'Include', WIN_VERSION, 'shared'],
    ['Windows Kits', '10', 'Include', WIN_VERSION, 'winrt'],
  ]
  include_dirs.append(['Windows Kits', '10', 'Include', WIN_VERSION, 'ucrt'])
  include_dirs.extend([
    vc_tools_parts + ['include'],
    vc_tools_parts + ['atlmfc', 'include'],
  ])
  libpath_dirs = [
    vc_tools_parts + ['lib', 'x86', 'store', 'references'],
    ['Windows Kits', '10', 'UnionMetadata', WIN_VERSION],
  ]
  # Common to x86, x64, and arm64
  env = collections.OrderedDict([
    # Yuck: These have a trailing \ character. No good way to represent this in
    # an OS-independent way.
    ('VSINSTALLDIR', [['.\\']]),
    ('VCINSTALLDIR', [['VC\\']]),
    ('INCLUDE', include_dirs),
    ('LIBPATH', libpath_dirs),
  ])
  # x86. Always use amd64_x86 cross, not x86 on x86.
  env['VCToolsInstallDir'] = [vc_tools_parts[:]]
  # Yuck: This one ends in a slash as well.
  env['VCToolsInstallDir'][0][-1] += '\\'
  env_x86 = collections.OrderedDict([
      (
          'PATH',
          [
              ['Windows Kits', '10', 'bin', WIN_VERSION, 'x64'],
              vc_tools_parts + ['bin', 'HostX64', 'x86'],
              vc_tools_parts + ['bin', 'HostX64', 'x64'
                                              ],  # Needed for mspdb1x0.dll.
          ]),
      ('LIB', [
          vc_tools_parts + ['lib', 'x86'],
          ['Windows Kits', '10', 'Lib', WIN_VERSION, 'um', 'x86'],
          ['Windows Kits', '10', 'Lib', WIN_VERSION, 'ucrt', 'x86'],
          vc_tools_parts + ['atlmfc', 'lib', 'x86'],
      ]),
  ])

  # x64.
  env_x64 = collections.OrderedDict([
      ('PATH', [
          ['Windows Kits', '10', 'bin', WIN_VERSION, 'x64'],
          vc_tools_parts + ['bin', 'HostX64', 'x64'],
      ]),
      ('LIB', [
          vc_tools_parts + ['lib', 'x64'],
          ['Windows Kits', '10', 'Lib', WIN_VERSION, 'um', 'x64'],
          ['Windows Kits', '10', 'Lib', WIN_VERSION, 'ucrt', 'x64'],
          vc_tools_parts + ['atlmfc', 'lib', 'x64'],
      ]),
  ])

  # arm64.
  env_arm64 = collections.OrderedDict([
      ('PATH', [
          ['Windows Kits', '10', 'bin', WIN_VERSION, 'x64'],
          vc_tools_parts + ['bin', 'HostX64', 'arm64'],
          vc_tools_parts + ['bin', 'HostX64', 'x64'],
      ]),
      ('LIB', [
          vc_tools_parts + ['lib', 'arm64'],
          ['Windows Kits', '10', 'Lib', WIN_VERSION, 'um', 'arm64'],
          ['Windows Kits', '10', 'Lib', WIN_VERSION, 'ucrt', 'arm64'],
          vc_tools_parts + ['atlmfc', 'lib', 'arm64'],
      ]),
  ])

  def BatDirs(dirs):
    return ';'.join(['%cd%\\' + os.path.join(*d) for d in dirs])
  set_env_prefix = os.path.join(target_dir, r'Windows Kits\10\bin\SetEnv')
  with open(set_env_prefix + '.cmd', 'w') as f:
    # The prologue changes the current directory to the root of the toolchain
    # package, so that path entries can be set up without needing ..\..\..\
    # components.
    f.write('@echo off\n'
            ':: Generated by win_toolchain\\package_from_installed.py.\n'
            'pushd %~dp0..\..\..\n')
    for var, dirs in env.items():
      f.write('set %s=%s\n' % (var, BatDirs(dirs)))
    f.write('if "%1"=="/x64" goto x64\n')
    f.write('if "%1"=="/arm64" goto arm64\n')

    for var, dirs in env_x86.items():
      f.write('set %s=%s%s\n' % (
          var, BatDirs(dirs), ';%PATH%' if var == 'PATH' else ''))
    f.write('goto :END\n')

    f.write(':x64\n')
    for var, dirs in env_x64.items():
      f.write('set %s=%s%s\n' % (
          var, BatDirs(dirs), ';%PATH%' if var == 'PATH' else ''))
    f.write('goto :END\n')

    f.write(':arm64\n')
    for var, dirs in env_arm64.items():
      f.write('set %s=%s%s\n' % (
          var, BatDirs(dirs), ';%PATH%' if var == 'PATH' else ''))
    f.write('goto :END\n')
    f.write(':END\n')
    # Restore the original directory.
    f.write('popd\n')
  with open(set_env_prefix + '.x86.json', 'wt', newline='') as f:
    assert not set(env.keys()) & set(env_x86.keys()), 'dupe keys'
    json.dump({'env': collections.OrderedDict(list(env.items()) + list(env_x86.items()))},
              f)
  with open(set_env_prefix + '.x64.json', 'wt', newline='') as f:
    assert not set(env.keys()) & set(env_x64.keys()), 'dupe keys'
    json.dump({'env': collections.OrderedDict(list(env.items()) + list(env_x64.items()))},
              f)
  with open(set_env_prefix + '.arm64.json', 'wt', newline='') as f:
    assert not set(env.keys()) & set(env_arm64.keys()), 'dupe keys'
    json.dump({'env': collections.OrderedDict(list(env.items()) + list(env_arm64.items()))},
              f)


def AddEnvSetup(files, include_arm):
  """We need to generate this file in the same way that the "from pieces"
  script does, so pull that in here."""
  tempdir = tempfile.mkdtemp()
  os.makedirs(os.path.join(tempdir, 'Windows Kits', '10', 'bin'))
  GenerateSetEnvCmd(tempdir)
  files.append((
      os.path.join(tempdir, 'Windows Kits', '10', 'bin', 'SetEnv.cmd'),
      'Windows Kits\\10\\bin\\SetEnv.cmd'))
  files.append((
      os.path.join(tempdir, 'Windows Kits', '10', 'bin', 'SetEnv.x86.json'),
      'Windows Kits\\10\\bin\\SetEnv.x86.json'))
  files.append((
      os.path.join(tempdir, 'Windows Kits', '10', 'bin', 'SetEnv.x64.json'),
      'Windows Kits\\10\\bin\\SetEnv.x64.json'))
  if include_arm:
    files.append((
        os.path.join(tempdir, 'Windows Kits', '10', 'bin', 'SetEnv.arm64.json'),
        'Windows Kits\\10\\bin\\SetEnv.arm64.json'))
  vs_version_file = os.path.join(tempdir, 'VS_VERSION')
  with open(vs_version_file, 'wt', newline='') as version:
    print(VS_VERSION, file=version)
  files.append((vs_version_file, 'VS_VERSION'))


def RenameToSha1(output):
  """Determine the hash in the same way that the unzipper does to rename the
  # .zip file."""
  print('Extracting to determine hash...')
  tempdir = tempfile.mkdtemp()
  old_dir = os.getcwd()
  os.chdir(tempdir)
  rel_dir = 'vs_files'
  with zipfile.ZipFile(
      os.path.join(old_dir, output), 'r', zipfile.ZIP_DEFLATED, True) as zf:
    zf.extractall(rel_dir)
  print('Hashing...')
  sha1 = get_toolchain_if_necessary.CalculateHash(rel_dir, None)
  # Shorten from forty characters to ten. This is still enough to avoid
  # collisions, while being less unwieldy and reducing the risk of MAX_PATH
  # failures.
  sha1 = sha1[:10]
  os.chdir(old_dir)
  shutil.rmtree(tempdir)
  final_name = sha1 + '.zip'
  os.rename(output, final_name)
  print('Renamed %s to %s.' % (output, final_name))


def main():
  if sys.version_info[0] < 3:
    print('This script requires Python 3')
    sys.exit(10)
  usage = 'usage: %prog [options] 2017|2019'
  parser = optparse.OptionParser(usage)
  parser.add_option('-w', '--winver', action='store', type='string',
                    dest='winver', default='10.0.18362.0',
                    help='Windows SDK version, such as 10.0.18362.0')
  parser.add_option('-d', '--dryrun', action='store_true', dest='dryrun',
                    default=False,
                    help='scan for file existence and prints statistics')
  parser.add_option('--noarm', action='store_false', dest='arm',
                    default=True,
                    help='Avoids arm parts of the SDK')
  parser.add_option('--override', action='store', type='string',
                    dest='override_dir', default=None,
                    help='Specify alternate bin/include/lib directory')
  parser.add_option('--repackage', action='store', type='string',
                    dest='repackage_dir', default=None,
                    help='Specify raw directory to be packaged, for hot fixes.')
  (options, args) = parser.parse_args()

  if options.repackage_dir:
    files = BuildRepackageFileList(options.repackage_dir)
  else:
    if len(args) != 1 or args[0] not in SUPPORTED_VS_VERSIONS:
      print('Must specify 2017 or 2019')
      parser.print_help();
      return 1

    if options.override_dir:
      if (not os.path.exists(os.path.join(options.override_dir, 'bin')) or
          not os.path.exists(os.path.join(options.override_dir, 'include')) or
          not os.path.exists(os.path.join(options.override_dir, 'lib'))):
        print('Invalid override directory - must contain bin/include/lib dirs')
        return 1

    global VS_VERSION
    VS_VERSION = args[0]
    global WIN_VERSION
    WIN_VERSION = options.winver
    global VC_TOOLS
    vs_path = GetVSPath()
    temp_tools_path = ExpandWildcards(vs_path, 'VC/Tools/MSVC/14.*.*')
    # Strip off the leading vs_path characters and switch back to / separators.
    VC_TOOLS = temp_tools_path[len(vs_path) + 1:].replace('\\', '/')

    print('Building file list for VS %s Windows %s...' % (VS_VERSION, WIN_VERSION))
    files = BuildFileList(options.override_dir, options.arm)

    AddEnvSetup(files, options.arm)

  if False:
    for f in files:
      print(f[0], '->', f[1])
    return 0

  output = 'out.zip'
  if os.path.exists(output):
    os.unlink(output)
  count = 0
  version_match_count = 0
  total_size = 0
  missing_files = False
  with zipfile.ZipFile(output, 'w', zipfile.ZIP_DEFLATED, True) as zf:
    for disk_name, archive_name in files:
      sys.stdout.write('\r%d/%d ...%s' % (count, len(files), disk_name[-40:]))
      sys.stdout.flush()
      count += 1
      if not options.repackage_dir and disk_name.count(WIN_VERSION) > 0:
        version_match_count += 1
      if os.path.exists(disk_name):
        total_size += os.path.getsize(disk_name)
        if not options.dryrun:
          zf.write(disk_name, archive_name)
      else:
        missing_files = True
        sys.stdout.write('\r%s does not exist.\n\n' % disk_name)
        sys.stdout.flush()
  sys.stdout.write('\r%1.3f GB of data in %d files, %d files for %s.%s\n' %
      (total_size / 1e9, count, version_match_count, WIN_VERSION, ' '*50))
  if options.dryrun:
    return 0
  if missing_files:
    raise Exception('One or more files were missing - aborting')
  if not options.repackage_dir and version_match_count == 0:
    raise Exception('No files found that match the specified winversion')
  sys.stdout.write('\rWrote to %s.%s\n' % (output, ' '*50))
  sys.stdout.flush()

  RenameToSha1(output)

  return 0


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