#!/usr/bin/python
# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.


"""
Library containing utility functions used for Chrome-specific build tasks.
"""


import functools
import glob
import logging
import os
import re
import shlex
import shutil

from chromite.buildbot import cbuildbot_results as results_lib
from chromite.lib import cros_build_lib
from chromite.lib import osutils


# Taken from external/gyp.git/pylib.
def _NameValueListToDict(name_value_list):
  """
  Takes an array of strings of the form 'NAME=VALUE' and creates a dictionary
  of the pairs.  If a string is simply NAME, then the value in the dictionary
  is set to True.  If VALUE can be converted to an integer, it is.
  """
  result = { }
  for item in name_value_list:
    tokens = item.split('=', 1)
    if len(tokens) == 2:
      # If we can make it an int, use that, otherwise, use the string.
      try:
        token_value = int(tokens[1])
      except ValueError:
        token_value = tokens[1]
      # Set the variable to the supplied value.
      result[tokens[0]] = token_value
    else:
      # No value supplied, treat it as a boolean and set it.
      result[tokens[0]] = True
  return result


def ProcessGypDefines(defines):
  """Validate and convert a string containing GYP_DEFINES to dictionary."""
  assert defines is not None
  return _NameValueListToDict(shlex.split(defines))


def DictToGypDefines(def_dict):
  """Convert a dict to GYP_DEFINES format."""
  def_list = []
  for k, v in def_dict.iteritems():
    def_list.append("%s='%s'" % (k, v))
  return ' '.join(def_list)


class Conditions(object):
  """Functions that return conditions used to construct Path objects.

  Condition functions returned by the public methods have signature
  f(gyp_defines, staging_flags).  For description of gyp_defines and
  staging_flags see docstring for StageChromeFromBuildDir().
  """

  @classmethod
  def _GypSet(cls, flag, value, gyp_defines, _staging_flags):
    val = gyp_defines.get(flag)
    return val == value if value is not None else bool(val)

  @classmethod
  def _GypNotSet(cls, flag, gyp_defines, staging_flags):
    return not cls._GypSet(flag, None, gyp_defines, staging_flags)

  @classmethod
  def _StagingFlagSet(cls, flag, _gyp_defines, staging_flags):
    return flag in staging_flags

  @classmethod
  def GypSet(cls, flag, value=None):
    """Returns condition that tests a gyp flag is set (possibly to a value)."""
    return functools.partial(cls._GypSet, flag, value)

  @classmethod
  def GypNotSet(cls, flag):
    """Returns condition that tests a gyp flag is not set."""
    return functools.partial(cls._GypNotSet, flag)

  @classmethod
  def StagingFlagSet(cls, flag):
    """Returns condition that tests a staging_flag is set."""
    return functools.partial(cls._StagingFlagSet, flag)


class MultipleMatchError(results_lib.StepFailure):
  """A glob pattern matches multiple files but a non-dir dest was specified."""


class MissingPathError(results_lib.StepFailure):
  """An expected path is non-existant."""


class MustNotBeDirError(results_lib.StepFailure):
  """The specified path should not be a directory, but is."""


class Copier(object):
  """File/directory copier.

  Provides destination stripping and permission setting functionality.
  """

  DEFAULT_BLACKLIST = (r'(^|.*/)\.svn($|/.*)',)

  def __init__(self, strip_bin=None, strip_flags=None, default_mode=0o644,
               dir_mode=0o755, exe_mode=0o755, blacklist=None):
    """Initialization.

    Args:
      strip_bin: Path to the program used to strip binaries.  If set to None,
                 binaries will not be stripped.
      strip_flags: A list of flags to pass to the |strip_bin| executable.
      default_mode: Default permissions to set on files.
      dir_mode: Mode to set for directories.
      exe_mode: Permissions to set on executables.
      blacklist: A list of path patterns to ignore during the copy.
    """
    self.strip_bin = strip_bin
    self.strip_flags = strip_flags
    self.default_mode = default_mode
    self.dir_mode = dir_mode
    self.exe_mode = exe_mode
    self.blacklist = blacklist
    if self.blacklist is None:
      self.blacklist = self.DEFAULT_BLACKLIST

  @staticmethod
  def Log(src, dest, directory):
    sep = ' [d] -> ' if directory else ' -> '
    logging.debug('%s %s %s', src, sep, dest)

  def _PathIsBlacklisted(self, path):
    for pattern in self.blacklist:
      if re.match(pattern, path):
        return True
    return False

  def _CopyFile(self, src, dest, path):
    """Perform the copy.

    Args:
      src: The path of the file/directory to copy.
      dest: The exact path of the destination.  Should not already exist.
      path: The Path instance containing copy operation modifiers (such as
            Path.exe, Path.strip, etc.)
    """
    assert not os.path.isdir(src), '%s: Not expecting a directory!' % src
    osutils.SafeMakedirs(os.path.dirname(dest), mode=self.dir_mode)
    if path.exe and self.strip_bin and path.strip and os.path.getsize(src) > 0:
      strip_flags = (['--strip-unneeded'] if self.strip_flags is None else
                     self.strip_flags)
      cros_build_lib.DebugRunCommand(
          [self.strip_bin] + strip_flags + ['-o', dest, src])
      shutil.copystat(src, dest)
    else:
      shutil.copy2(src, dest)

    mode = path.mode
    if mode is None:
      mode = self.exe_mode if path.exe else self.default_mode
    os.chmod(dest, mode)

  def Copy(self, src_base, dest_base, path, strict=False, sloppy=False):
    """Copy artifact(s) from source directory to destination.

    Args:
      src_base: The directory to apply the src glob pattern match in.
      dest_base: The directory to copy matched files to.  |Path.dest|.
      path: A Path instance that specifies what is to be copied.
      strict: If set, enforce that all optional files are copied.
      sloppy: If set, ignore when mandatory artifacts are missing.

    Returns:
      A list of the artifacts copied.
    """
    assert not (strict and sloppy), 'strict and sloppy are not compatible.'
    copied_paths = []
    src = os.path.join(src_base, path.src)
    if not src.endswith('/') and os.path.isdir(src):
      raise MustNotBeDirError('%s must not be a directory\n'
                              'Aborting copy...' % (src,))
    paths = glob.glob(src)
    if not paths:
      if ((strict and not path.optional) or
          (not strict and not (path.optional or path.cond) and not sloppy)):
        msg = ('%s does not exist and is required.\n'
               'You can bypass this error with --sloppy.\n'
               'Aborting copy...' % src)
        raise MissingPathError(msg)
      elif path.optional or (not strict and path.cond):
        logging.debug('%s does not exist and is optional.  Skipping.', src)
      else:
        logging.warn('%s does not exist and is required.  Skipping anyway.',
                     src)
    elif len(paths) > 1 and path.dest and not path.dest.endswith('/'):
      raise MultipleMatchError(
          'Glob pattern %r has multiple matches, but dest %s '
          'is not a directory.\n'
          'Aborting copy...' % (path.src, path.dest))
    else:
      for p in paths:
        rel_src = os.path.relpath(p, src_base)
        if path.dest is None:
          rel_dest = rel_src
        elif path.dest.endswith('/'):
          rel_dest = os.path.join(path.dest, os.path.basename(p))
        else:
          rel_dest = path.dest
        assert not rel_dest.endswith('/')
        dest = os.path.join(dest_base, rel_dest)

        copied_paths.append(p)
        self.Log(p, dest, os.path.isdir(p))
        if os.path.isdir(p):
          for sub_path in osutils.DirectoryIterator(p):
            rel_path = os.path.relpath(sub_path, p)
            sub_dest = os.path.join(dest, rel_path)
            if self._PathIsBlacklisted(rel_path):
              continue
            if sub_path.endswith('/'):
              osutils.SafeMakedirs(sub_dest, mode=self.dir_mode)
            else:
              self._CopyFile(sub_path, sub_dest, path)
        else:
          self._CopyFile(p, dest, path)

    return copied_paths


class Path(object):
  """Represents an artifact to be copied from build dir to staging dir."""

  def __init__(self, src, exe=False, cond=None, dest=None, mode=None,
               optional=False, strip=True):
    """Initializes the object.

    Args:
      src: The relative path of the artifact.  Can be a file or a directory.
           Can be a glob pattern.
      exe: Identifes the path as either being an executable or containing
           executables.  Executables may be stripped during copy, and have
           special permissions set.  We currently only support stripping of
           specified files and glob patterns that return files.  If |src| is a
           directory or contains directories, the content of the directory will
           not be stripped.
      cond: A condition (see Conditions class) to test for in deciding whether
            to process this artifact. If supplied, the artifact will be treated
            as optional unless --strict is supplied.
      dest: Name to give to the target file/directory.  Defaults to keeping the
            same name as the source.
      mode: The mode to set for the matched files, and the contents of matched
            directories.
      optional: Whether to enforce the existence of the artifact.  If unset, the
                script errors out if the artifact does not exist.  In 'sloppy'
                mode, the Copier class treats all artifacts as optional.
      strip: If |exe| is set, whether to strip the executable.
    """
    self.src = src
    self.exe = exe
    self.cond = cond
    self.dest = dest
    self.mode = mode
    self.optional = optional
    self.strip = strip

  def ShouldProcess(self, gyp_defines, staging_flags):
    """Tests whether this artifact should be copied."""
    if self.cond:
      return self.cond(gyp_defines, staging_flags)
    return True


_DISABLE_NACL = 'disable_nacl'
_USE_DRM = 'use_drm'


_CHROME_INTERNAL_FLAG = 'chrome_internal'
_CONTENT_SHELL_FLAG = 'content_shell'
_HIGHDPI_FLAG = 'highdpi'
_PDF_FLAG = 'chrome_pdf'
STAGING_FLAGS = (_CHROME_INTERNAL_FLAG, _CONTENT_SHELL_FLAG, _HIGHDPI_FLAG,
                 _PDF_FLAG)

_CHROME_SANDBOX_DEST = 'chrome-sandbox'
C = Conditions


_COPY_PATHS = (
  Path('ash_shell',
       cond=C.GypSet(_USE_DRM)),
  Path('aura_demo',
       cond=C.GypSet(_USE_DRM)),
  Path('chrome',
       exe=True),
  Path('chrome_sandbox', mode=0o4755,
       dest=_CHROME_SANDBOX_DEST),
  Path('chrome-wrapper'),
  Path('chrome_100_percent.pak'),
  Path('chrome_200_percent.pak',
       cond=C.StagingFlagSet(_HIGHDPI_FLAG)),
  Path('content_shell',
       exe=True,
       cond=C.StagingFlagSet(_CONTENT_SHELL_FLAG)),
  Path('content_shell.pak',
       cond=C.StagingFlagSet(_CONTENT_SHELL_FLAG)),
  Path('keyboard_resources.pak'),
  Path('lib/*.so',
       exe=True,
       cond=C.GypSet('component', value='shared_library')),
  # Set as optional for backwards compatibility.
  Path('lib/libpeerconnection.so',
       exe=True,
       cond=C.StagingFlagSet(_CHROME_INTERNAL_FLAG),
       optional=True),
  Path('libffmpegsumo.so',
       exe=True),
  Path('libpdf.so',
       exe=True,
       cond=C.StagingFlagSet(_PDF_FLAG)),
  Path('libppGoogleNaClPluginChrome.so',
       exe=True,
       cond=C.GypNotSet(_DISABLE_NACL)),
  Path('libosmesa.so',
       exe=True,
       optional=True),
  # Widevine binaries are already pre-stripped.  In addition, they don't
  # play well with the binutils stripping tools, so skip stripping.
  Path('libwidevinecdmadapter.so',
       exe=True,
       strip=False,
       cond=C.StagingFlagSet(_CHROME_INTERNAL_FLAG)),
  Path('libwidevinecdm.so',
       exe=True,
       strip=False,
       cond=C.StagingFlagSet(_CHROME_INTERNAL_FLAG)),
  Path('locales/'),
  # Do not strip the nacl_helper_bootstrap binary because the binutils
  # objcopy/strip mangles the ELF program headers.
  Path('nacl_helper_bootstrap',
       exe=True, strip=False,
       cond=C.GypNotSet(_DISABLE_NACL)),
  Path('nacl_irt_*.nexe',
       cond=C.GypNotSet(_DISABLE_NACL)),
  Path('nacl_helper',
       exe=True,
       optional=True,
       cond=C.GypNotSet(_DISABLE_NACL)),
  Path('pnacl/',
       cond=C.GypNotSet(_DISABLE_NACL)),
  Path('resources/'),
  Path('resources.pak'),
  Path('xdg-settings'),
  Path('*.png'),
)


def _FixPermissions(dest_base):
  """Last minute permission fixes."""
  cros_build_lib.DebugRunCommand(['chmod', '-R', 'a+r', dest_base])
  cros_build_lib.DebugRunCommand(
      ['find', dest_base, '-perm', '/110', '-exec', 'chmod', 'a+x', '{}', '+'])


def StageChromeFromBuildDir(staging_dir, build_dir, strip_bin, strict=False,
                            sloppy=False, gyp_defines=None, staging_flags=None,
                            strip_flags=None):
  """Populates a staging directory with necessary build artifacts.

  If |strict| is set, then we decide what to stage based on the |gyp_defines|
  and |staging_flags| passed in.  Otherwise, we stage everything that we know
  about, that we can find.

  Args:
    staging_dir: Path to an empty staging directory.
    build_dir: Path to location of Chrome build artifacts.
    strip_bin: Path to executable used for stripping binaries.
    strict: If set, decide what to stage based on the |gyp_defines| and
            |staging_flags| passed in, and enforce that all optional files
            are copied.  Otherwise, we stage optional files if they are
            there, but we don't complain if they're not.
    sloppy: Ignore when mandatory artifacts are missing.
    gyp_defines: A dictionary (i.e., one returned by ProcessGypDefines)
      containing GYP_DEFINES Chrome was built with.
    staging_flags: A list of extra staging flags.  Valid flags are specified in
      STAGING_FLAGS.
    strip_flags: A list of flags to pass to the tool used to strip binaries.
  """
  os.mkdir(os.path.join(staging_dir, 'plugins'), 0o755)

  if gyp_defines is None:
    gyp_defines = {}
  if staging_flags is None:
    staging_flags = []

  copier = Copier(strip_bin=strip_bin, strip_flags=strip_flags)
  copied_paths = []
  for p in _COPY_PATHS:
    if not strict or p.ShouldProcess(gyp_defines, staging_flags):
      copied_paths += copier.Copy(build_dir, staging_dir, p, strict=strict,
                                  sloppy=sloppy)

  if not copied_paths:
    raise MissingPathError('Couldn\'t find anything to copy!\n'
                           'Are you looking in the right directory?\n'
                           'Aborting copy...')

  _FixPermissions(staging_dir)
