#!/usr/bin/python
# Copyright 2013 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.

"""Downloads, builds (with instrumentation) and installs shared libraries."""

import argparse
import ast
import fcntl
import os
import platform
import re
import shlex
import shutil
import subprocess
import sys

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

def unescape_flags(s):
  """Un-escapes build flags received from GYP.

  GYP escapes build flags as if they are to be inserted directly into a command
  line, wrapping each flag in double quotes. When flags are passed via
  CFLAGS/LDFLAGS instead, double quotes must be dropped.
  """
  if not s:
    return ''
  try:
    return ' '.join(ast.literal_eval(s))
  except (SyntaxError, ValueError):
    return ' '.join(shlex.split(s))


def real_path(path_relative_to_gyp):
  """Returns the absolute path to a file.

  GYP generates paths relative to the location of the .gyp file, which is one
  level above the location of this script. This function converts them to
  absolute paths.
  """
  return os.path.realpath(os.path.join(SCRIPT_ABSOLUTE_PATH, '..',
                                       path_relative_to_gyp))


class InstrumentedPackageBuilder(object):
  """Checks out and builds a single instrumented package."""
  def __init__(self, args, clobber):
    self._cc = args.cc
    self._cxx = args.cxx
    self._extra_configure_flags = unescape_flags(args.extra_configure_flags)
    self._libdir = args.libdir
    self._package = args.package
    self._patch = real_path(args.patch) if args.patch else None
    self._pre_build = \
        real_path(args.pre_build) if args.pre_build else None
    self._sanitizer = args.sanitizer
    self._verbose = args.verbose
    self._clobber = clobber
    self._working_dir = os.path.join(
        real_path(args.intermediate_dir), self._package, '')

    product_dir = real_path(args.product_dir)
    self._destdir = os.path.join(
        product_dir, 'instrumented_libraries', self._sanitizer)
    self._source_archives_dir = os.path.join(
        product_dir, 'instrumented_libraries', 'sources', self._package)

    self._cflags = unescape_flags(args.cflags)
    if args.sanitizer_blacklist:
      blacklist_file = real_path(args.sanitizer_blacklist)
      self._cflags += ' -fsanitize-blacklist=%s' % blacklist_file

    self._ldflags = unescape_flags(args.ldflags)

    self.init_build_env()

    # Initialized later.
    self._source_dir = None
    self._source_archives = None

  def init_build_env(self):
    self._build_env = os.environ.copy()

    self._build_env['CC'] = self._cc
    self._build_env['CXX'] = self._cxx

    self._build_env['CFLAGS'] = self._cflags
    self._build_env['CXXFLAGS'] = self._cflags
    self._build_env['LDFLAGS'] = self._ldflags

    if self._sanitizer == 'asan':
      # Do not report leaks during the build process.
      self._build_env['ASAN_OPTIONS'] = \
          '%s:detect_leaks=0' % self._build_env.get('ASAN_OPTIONS', '')

    # libappindicator1 needs this.
    self._build_env['CSC'] = '/usr/bin/mono-csc'

  def shell_call(self, command, env=None, cwd=None, ignore_ret_code=False):
    """Wrapper around subprocess.Popen().

    Calls command with specific environment and verbosity using
    subprocess.Popen().
    """
    child = subprocess.Popen(
        command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
        env=env, shell=True, cwd=cwd)
    stdout, stderr = child.communicate()
    if ignore_ret_code:
      if self._verbose:
        print stdout
      return
    if self._verbose or child.returncode:
      print stdout
    if child.returncode:
      raise Exception('Failed to run: %s' % command)

  def maybe_download_source(self):
    """Checks out the source code (if needed).

    Checks out the source code for the package, if required (i.e. unless running
    in no-clobber mode). Initializes self._source_dir and self._source_archives.
    """
    get_fresh_source = self._clobber or not os.path.exists(self._working_dir)
    if get_fresh_source:
      shutil.rmtree(self._working_dir, ignore_errors=True)
      os.makedirs(self._working_dir)

      # Download one source package at a time, otherwise, there will
      # be connection errors in gnutls_handshake().
      lock = open('apt-source-lock', 'w')
      fcntl.flock(lock, fcntl.LOCK_EX)
      self.shell_call('apt-get source %s' % self._package,
                      cwd=self._working_dir)
      fcntl.flock(lock, fcntl.LOCK_UN)

    (dirpath, dirnames, filenames) = os.walk(self._working_dir).next()

    if len(dirnames) != 1:
      raise Exception(
          '`apt-get source %s\' must create exactly one subdirectory.'
              % self._package)
    self._source_dir = os.path.join(dirpath, dirnames[0], '')

    if len(filenames) == 0:
      raise Exception('Can\'t find source archives after `apt-get source %s\'.'
         % self._package)
    self._source_archives = \
        [os.path.join(dirpath, filename) for filename in filenames]

    return get_fresh_source

  def patch_source(self):
    if self._patch:
      self.shell_call('patch -p1 -i %s' % self._patch, cwd=self._source_dir)
    if self._pre_build:
      self.shell_call(self._pre_build, cwd=self._source_dir)

  def copy_source_archives(self):
    """Copies the downloaded source archives to the output dir.

    For license compliance purposes, every Chromium build that includes
    instrumented libraries must include their full source code.
    """
    shutil.rmtree(self._source_archives_dir, ignore_errors=True)
    os.makedirs(self._source_archives_dir)
    for filename in self._source_archives:
      shutil.copy(filename, self._source_archives_dir)
    if self._patch:
      shutil.copy(self._patch, self._source_archives_dir)

  def download_build_install(self):
    got_fresh_source = self.maybe_download_source()
    if got_fresh_source:
      self.patch_source()
      self.copy_source_archives()

    if not os.path.exists(self.dest_libdir()):
      os.makedirs(self.dest_libdir())

    try:
      self.build_and_install()
    except Exception as exception:
      print 'ERROR: Failed to build package %s. Have you run ' \
            'src/third_party/instrumented_libraries/scripts/' \
            'install-build-deps.sh?' % \
            self._package
      print
      raise

    # Touch a text file to indicate package is installed.
    stamp_file = os.path.join(self._destdir, '%s.txt' % self._package)
    open(stamp_file, 'w').close()

    # Remove downloaded package and generated temporary build files. Failed
    # builds intentionally skip this step to help debug build failures.
    if self._clobber:
      self.shell_call('rm -rf %s' % self._working_dir)

  def fix_rpaths(self, directory):
    # TODO(eugenis): reimplement fix_rpaths.sh in Python.
    script = real_path('scripts/fix_rpaths.sh')
    self.shell_call("%s %s" % (script, directory))

  def temp_dir(self):
    """Returns the directory which will be passed to `make install'."""
    return os.path.join(self._source_dir, 'debian', 'instrumented_build')

  def temp_libdir(self):
    """Returns the directory under temp_dir() containing the DSOs."""
    return os.path.join(self.temp_dir(), self._libdir)

  def dest_libdir(self):
    """Returns the final location of the DSOs."""
    return os.path.join(self._destdir, self._libdir)

  def cleanup_after_install(self):
    """Removes unneeded files in self.temp_libdir()."""
    # .la files are not needed, nuke them.
    # In case --no-static is not supported, nuke any static libraries we built.
    self.shell_call(
        'find %s -name *.la -or -name *.a | xargs rm -f' % self.temp_libdir())
    # .pc files are not needed.
    self.shell_call('rm %s/pkgconfig -rf' % self.temp_libdir())

  def make(self, args, env=None, cwd=None, ignore_ret_code=False):
    """Invokes `make'.

    Invokes `make' with the specified args, using self._build_env and
    self._source_dir by default.
    """
    if cwd is None:
      cwd = self._source_dir
    if env is None:
      env = self._build_env
    cmd = ['make'] + args
    self.shell_call(' '.join(cmd), env=env, cwd=cwd,
                    ignore_ret_code=ignore_ret_code)

  def make_install(self, args, **kwargs):
    """Invokes `make install'."""
    self.make(['install'] + args, **kwargs)

  def build_and_install(self):
    """Builds and installs the DSOs.

    Builds the package with ./configure + make, installs it to a temporary
    location, then moves the relevant files to their permanent location.
    """
    configure_cmd = './configure --libdir=/%s/ %s' % (
        self._libdir, self._extra_configure_flags)
    self.shell_call(configure_cmd, env=self._build_env, cwd=self._source_dir)

    # Some makefiles use BUILDROOT or INSTALL_ROOT instead of DESTDIR.
    args = ['DESTDIR', 'BUILDROOT', 'INSTALL_ROOT']
    make_args = ['%s=%s' % (name, self.temp_dir()) for name in args]
    self.make(make_args)

    self.make_install(make_args)

    self.cleanup_after_install()

    self.fix_rpaths(self.temp_libdir())

    # Now move the contents of the temporary destdir to their final place.
    # We only care for the contents of LIBDIR.
    self.shell_call('cp %s/* %s/ -rdf' % (self.temp_libdir(),
                                          self.dest_libdir()))


class LibcapBuilder(InstrumentedPackageBuilder):
  def build_and_install(self):
    # libcap2 doesn't have a configure script
    build_args = ['CC', 'CXX', 'CFLAGS', 'CXXFLAGS', 'LDFLAGS']
    make_args = [
        '%s="%s"' % (name, self._build_env[name]) for name in build_args
    ]
    self.make(make_args)

    install_args = [
        'DESTDIR=%s' % self.temp_dir(),
        'lib=%s' % self._libdir,
        # Skip a step that requires sudo.
        'RAISE_SETFCAP=no'
    ]
    self.make_install(install_args)

    self.cleanup_after_install()

    self.fix_rpaths(self.temp_libdir())

    # Now move the contents of the temporary destdir to their final place.
    # We only care for the contents of LIBDIR.
    self.shell_call('cp %s/* %s/ -rdf' % (self.temp_libdir(),
                                          self.dest_libdir()))


class Libpci3Builder(InstrumentedPackageBuilder):
  def package_version(self):
    """Guesses libpci3 version from source directory name."""
    dir_name = os.path.split(os.path.normpath(self._source_dir))[-1]
    match = re.match('pciutils-(\d+\.\d+\.\d+)', dir_name)
    if match is None:
      raise Exception(
          'Unable to guess libpci3 version from directory name: %s' %  dir_name)
    return match.group(1)

  def temp_libdir(self):
    # DSOs have to be picked up from <source_dir>/lib, since `make install'
    # doesn't actualy install them anywhere.
    return os.path.join(self._source_dir, 'lib')

  def build_and_install(self):
    # pciutils doesn't have a configure script
    # This build process follows debian/rules.
    self.shell_call('mkdir -p %s-udeb/usr/bin' % self.temp_dir())

    build_args = ['CC', 'CXX', 'CFLAGS', 'CXXFLAGS', 'LDFLAGS']
    make_args = [
        '%s="%s"' % (name, self._build_env[name]) for name in build_args
    ]
    make_args += [
        'LIBDIR=/%s/' % self._libdir,
        'PREFIX=/usr',
        'SBINDIR=/usr/bin',
        'IDSDIR=/usr/share/misc',
        'SHARED=yes',
        # pciutils-3.2.1 (Trusty) fails to build due to unresolved libkmod
        # symbols. The binary package has no dependencies on libkmod, so it
        # looks like it was actually built without libkmod support.
       'LIBKMOD=no',
    ]
    self.make(make_args)

    # `make install' is not needed.
    self.fix_rpaths(self.temp_libdir())

    # Now install the DSOs to their final place.
    self.shell_call(
        'install -m 644 %s/libpci.so* %s' % (self.temp_libdir(),
                                             self.dest_libdir()))
    self.shell_call(
        'ln -sf libpci.so.%s %s/libpci.so.3' % (self.package_version(),
                                                self.dest_libdir()))


class NSSBuilder(InstrumentedPackageBuilder):
  def build_and_install(self):
    # NSS uses a build system that's different from configure/make/install. All
    # flags must be passed as arguments to make.
    make_args = [
        # Do an optimized build.
        'BUILD_OPT=1',
        # CFLAGS/CXXFLAGS should not be used, as doing so overrides the flags in
        # the makefile completely. The only way to append our flags is to tack
        # them onto CC/CXX.
        'CC="%s %s"' % (self._build_env['CC'], self._build_env['CFLAGS']),
        'CXX="%s %s"' % (self._build_env['CXX'], self._build_env['CXXFLAGS']),
        # We need to override ZDEFS_FLAG at least to avoid -Wl,-z,defs, which
        # is not compatible with sanitizers. We also need some way to pass
        # LDFLAGS without overriding the defaults. Conveniently, ZDEF_FLAG is
        # always appended to link flags when building NSS on Linux, so we can
        # just add our LDFLAGS here.
        'ZDEFS_FLAG="-Wl,-z,nodefs %s"' % self._build_env['LDFLAGS'],
        'NSPR_INCLUDE_DIR=/usr/include/nspr',
        'NSPR_LIB_DIR=%s' % self.dest_libdir(),
        'NSS_ENABLE_ECC=1'
    ]
    if platform.architecture()[0] == '64bit':
      make_args.append('USE_64=1')

    # Make sure we don't override the default flags in the makefile.
    for variable in ['CFLAGS', 'CXXFLAGS', 'LDFLAGS']:
      del self._build_env[variable]

    # Hardcoded paths.
    temp_dir = os.path.join(self._source_dir, 'nss')
    temp_libdir = os.path.join(temp_dir, 'lib')

    # The build happens in <source_dir>/nss.  Building fails after all
    # the required DSOs have been built, so ignore the error.
    self.make(make_args, cwd=temp_dir, ignore_ret_code=True)

    self.fix_rpaths(temp_libdir)

    # 'make install' is not supported. Copy the DSOs manually.
    for (dirpath, dirnames, filenames) in os.walk(temp_libdir):
      for filename in filenames:
        if filename.endswith('.so'):
          full_path = os.path.join(dirpath, filename)
          if self._verbose:
            print 'download_build_install.py: installing %s' % full_path
          shutil.copy(full_path, self.dest_libdir())


class StubBuilder(InstrumentedPackageBuilder):
  def download_build_install(self):
    self._touch(os.path.join(self._destdir, '%s.txt' % self._package))
    self.shell_call('mkdir -p %s' % self.dest_libdir())
    self._touch(os.path.join(self.dest_libdir(), '%s.so.0' % self._package))

  def _touch(self, path):
    with open(path, 'w'):
      pass


def main():
  parser = argparse.ArgumentParser(
      description='Download, build and install an instrumented package.')

  parser.add_argument('-p', '--package', required=True)
  parser.add_argument(
      '-i', '--product-dir', default='.',
      help='Relative path to the directory with chrome binaries')
  parser.add_argument(
      '-m', '--intermediate-dir', default='.',
      help='Relative path to the directory for temporary build files')
  parser.add_argument('--extra-configure-flags', default='')
  parser.add_argument('--cflags', default='')
  parser.add_argument('--ldflags', default='')
  parser.add_argument('-s', '--sanitizer', required=True,
                               choices=['asan', 'msan', 'tsan'])
  parser.add_argument('-v', '--verbose', action='store_true')
  parser.add_argument('--cc')
  parser.add_argument('--cxx')
  parser.add_argument('--patch', default='')
  # This should be a shell script to run before building specific libraries.
  # This will be run after applying the patch above.
  parser.add_argument('--pre-build', default='')
  parser.add_argument('--build-method', default='destdir')
  parser.add_argument('--sanitizer-blacklist', default='')
  # The LIBDIR argument to configure/make.
  parser.add_argument('--libdir', default='lib')

  # Ignore all empty arguments because in several cases gyp passes them to the
  # script, but ArgumentParser treats them as positional arguments instead of
  # ignoring (and doesn't have such options).
  args = parser.parse_args([arg for arg in sys.argv[1:] if len(arg) != 0])

  # Clobber by default, unless the developer wants to hack on the package's
  # source code.
  clobber = \
        (os.environ.get('INSTRUMENTED_LIBRARIES_NO_CLOBBER', '') != '1')

  if args.build_method == 'destdir':
    builder = InstrumentedPackageBuilder(args, clobber)
  elif args.build_method == 'custom_nss':
    builder = NSSBuilder(args, clobber)
  elif args.build_method == 'custom_libcap':
    builder = LibcapBuilder(args, clobber)
  elif args.build_method == 'custom_libpci3':
    builder = Libpci3Builder(args, clobber)
  elif args.build_method == 'stub':
    builder = StubBuilder(args, clobber)
  else:
    raise Exception('Unrecognized build method: %s' % args.build_method)

  builder.download_build_install()

if __name__ == '__main__':
  main()
