#!/usr/bin/env python
# Copyright (c) 2012 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.

"""Takes the output of the build step and turns it into a compressed
archive ready for distribution.

This script assumes the build script has been run to compile the add-in.
It zips up all files required for the add-in installation and places the
result in out/vs_addin/vs_addin.tgz.
"""
from __future__ import print_function

import os
import re
import fileinput
import win32api
import shutil
import tarfile
import zipfile
import string
import sys
from os.path import join

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))

# Checkout root
ROOT = os.path.dirname(os.path.dirname(SCRIPT_DIR))

# Root output directory.
BUILD_DIR = join(ROOT, 'out', 'vs_addin')
STAGING_DIR = join(BUILD_DIR, 'staging')

# Directory that contains the build assemblies.
ASSEMBLY_DIRECTORY_2010 = join(BUILD_DIR, '2010', 'Debug')
ASSEMBLY_DIRECTORY_2012 = join(BUILD_DIR, '2012', 'Debug')

# Directory containing static installer resources.
RESOURCE_DIRECTORY = join(SCRIPT_DIR, 'InstallerResources')

# Base name of the final zip file.
OUTPUT_NAME = join(BUILD_DIR, 'vs_addin.tgz')

# AddIn metadata file path. We will modify this with the version #.
ADDIN_METADATA = join(RESOURCE_DIRECTORY, 'NativeClientVSAddIn.AddIn')

# AddIn dll file path. We will obtain our add-in version from this.
ADDIN_ASSEMBLY_2010 = join(ASSEMBLY_DIRECTORY_2010, 'NativeClientVSAddIn.dll')
ADDIN_ASSEMBLY_2012 = join(ASSEMBLY_DIRECTORY_2012, 'NativeClientVSAddIn.dll')

# Regex list to exclude from the archive. If a file path matches any of the
# expressions during a call to AddFolderToArchive it is excluded from the
# archive file.
EXCLUDES = [
    r'\.svn', # Exclude .svn directories.
    r'\.swp$', # Exclude .swp files.
    r'\.pyc$', # Exclude .pyc files.
    r'examples\\.*\\chrome_data',
    r'examples\\.*\\Debug',
    r'examples\\.*\\newlib',
    r'examples\\.*\\glibc',
    r'examples\\.*\\PNaCl',
    r'examples\\.*\\win',
    r'examples\\.*\\ipch',
    r'examples\\.*\\*.sdf',
    r'examples\\.*\\*.suo',
    # Exclude .AddIn file for now since we need to modify it with version info.
    re.escape(ADDIN_METADATA)]

# List of source/destination pairs to include in archive file.
FILE_LIST = [
  (ADDIN_ASSEMBLY_2010, '2010'),
  (ADDIN_ASSEMBLY_2012, '2012'),
  (join(ASSEMBLY_DIRECTORY_2010, 'NativeClientVSAddIn.AddIn'), '2010'),
  (join(ASSEMBLY_DIRECTORY_2012, 'NativeClientVSAddIn.AddIn'), '2012'),
  (join(ASSEMBLY_DIRECTORY_2010, 'NaCl.Build.CPPTasks.dll'), 'NaCl')]


def MakeDir(dirname):
  """Create a directory if it doesn't already exist."""
  if not os.path.isdir(dirname):
    os.makedirs(dirname)


def StageDirectory(dir_to_copy):
  """Recursively add a directory to the staging directory.

  Args:
    dir_to_copy: Directory to add.
    basedir: The directory with the staging directory.
  """
  for root, _, files in os.walk(dir_to_copy):
    for filename in files:
      src_path = join(root, filename)

      # If the file path matches an exclude, don't include it.
      if any(re.search(expr, src_path) for expr in EXCLUDES):
        continue

      relative_root = os.path.relpath(root, dir_to_copy)
      dest_path = join(STAGING_DIR, relative_root, filename)

      MakeDir(os.path.dirname(dest_path))
      assert(not os.path.exists(dest_path))
      shutil.copy(src_path, dest_path)


def AddFolderToArchive(path, archive):
  """Recursively adds a directory to an open archive object.

  The archive must already be open and it is not closed by this function.

  Args:
    path: Direcotory to add.
    archive: Open archive file.
  """
  for root, _, files in os.walk(path):
    for filename in files:
      src_path = join(root, filename)
      archive_dir = os.path.join('vs_addin', os.path.relpath(root, path))
      archive_name = join(archive_dir, filename)
      print('Archiving: %s' % archive_name)
      archive.add(src_path, archive_name)


def CopyAddinFile(assembly, path, vs_version):
  """Copy the .AddIn file to the given path while making the necessary
  replacements.

  The version number is obtained from the NativeClientAddIn.dll assembly which
  is built during the build process.
  """
  infopath = '\\VarFileInfo\\Translation'
  pairs = win32api.GetFileVersionInfo(assembly, infopath)
  lang, codepage = pairs[0]
  infopath = u'\\StringFileInfo\\%04X%04X\\ProductVersion' % (lang, codepage)
  prodVersion = win32api.GetFileVersionInfo(assembly, infopath)
  version = '[%s]' % prodVersion
  print('NaCl VS Add-in %s version: %s' % (vs_version, version))

  metadata_filename = os.path.basename(ADDIN_METADATA)
  modified_file = join(path, metadata_filename)

  # Copy the metadata file to new location and modify the version info.
  with open(ADDIN_METADATA, 'r') as source_file:
    with open(modified_file, 'w') as dest_file:
      data = source_file.read()
      replacements = {'VS_VERSION': vs_version, 'ADDIN_VERSION': version}
      data = string.Template(data).substitute(replacements)
      dest_file.write(data)


def Error(msg):
  sys.stderr.write(msg + '\n')
  sys.exit(1)


def CopyWithReplacement(src, dest, replacements):
  MakeDir(dest)
  src_basename = os.path.basename(src)
  dest_basename = os.path.basename(dest)

  olddir = os.getcwd()
  try:
    os.chdir(src)
    for root, dirs, filenames in os.walk('.'):
      for filename in filenames:
        srcfile = join(root, filename)
        # skip non-files, in particular .svn folders.
        if not os.path.isfile(srcfile):
          continue

        destdir = join(dest, root.replace(src_basename, dest_basename))
        destdir = os.path.normpath(destdir)
        MakeDir(destdir)

        destfile = join(destdir, filename.replace(src_basename, dest_basename))
        if os.path.exists(destfile):
          print('Skipping: %s' % destfile)
          continue

        with open(srcfile, "rb") as f:
          data = f.read()
          for pat, subst in replacements.iteritems():
            data = data.replace(pat, subst)

        with open(destfile, "wb") as f:
          f.write(data)
  finally:
    os.chdir(olddir)


def main(args):
  if not os.path.exists(BUILD_DIR):
    Error("build dir not found: %s" % BUILD_DIR)

  CopyAddinFile(ADDIN_ASSEMBLY_2010, ASSEMBLY_DIRECTORY_2010, '10.0')
  CopyAddinFile(ADDIN_ASSEMBLY_2012, ASSEMBLY_DIRECTORY_2012, '11.0')

  print("Staging package in %s" % STAGING_DIR)
  if os.path.exists(STAGING_DIR):
    shutil.rmtree(STAGING_DIR)

  # Start by staging the entire resource tree
  StageDirectory(RESOURCE_DIRECTORY)

  # Then stage anything in the FILE_LIST
  for source, dest in FILE_LIST:
    file_name = os.path.basename(source)
    dest = join(STAGING_DIR, dest, file_name)
    assert(not os.path.exists(dest))
    MakeDir(os.path.dirname(dest))
    shutil.copy(source, dest)

  # Duplicate the NaCl64 platform but rename it to NaCl32
  src = join(RESOURCE_DIRECTORY, 'NaCl64')

  # Create NaCl32
  dest = join(STAGING_DIR, 'NaCl32')
  CopyWithReplacement(src, dest, {'x86_64': 'i686', '64': '32'})

  # Create NaClARM
  arm_replacements = {
      'x86_64': 'arm',
      '64': 'arm',
      'win_x86': 'win_arm'
  }

  dest = join(STAGING_DIR, 'NaClARM')
  CopyWithReplacement(src, dest, arm_replacements)

  # Create PNaCl
  pnacl_replacements = {
      'NaCl64': 'PNaCl',
      'x86_64': 'pnacl',
      '64': '32',
      '.nexe': '.pexe',
      'nacl_link.xml': 'pnacl_link.xml',
      '$(ProjectName)_$(PlatformArchitecture)': '$(ProjectName)',
  }

  dest = join(STAGING_DIR, 'PNaCl')
  CopyWithReplacement(src, dest, pnacl_replacements)

  # Create archive
  archive = tarfile.open(OUTPUT_NAME, 'w:gz')
  AddFolderToArchive(STAGING_DIR, archive)
  archive.close()
  return 0


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