# Copyright 2010 Google Inc.
# All Rights Reserved.
#
# Author: Tim Haloun (thaloun@google.com)
#         Daniel Petersson (dape@google.com)
#
import os
import SCons.Util

class LibraryInfo:
  """Records information on the libraries defined in a build configuration.

  Attributes:
    lib_targets: Dictionary of library target params for lookups in
        ExtendComponent().
    prebuilt_libraries: Set of all prebuilt static libraries.
    system_libraries: Set of libraries not found in the above (used to detect
        out-of-order build rules).
  """

  # Dictionary of LibraryInfo objects keyed by BUILD_TYPE value.
  __library_info = {}

  @staticmethod
  def get(env):
    """Gets the LibraryInfo object for the current build type.

    Args:
      env: The environment object.

    Returns:
      The LibraryInfo object.
    """
    return LibraryInfo.__library_info.setdefault(env['BUILD_TYPE'],
                                                 LibraryInfo())

  def __init__(self):
    self.lib_targets = {}
    self.prebuilt_libraries = set()
    self.system_libraries = set()


def _GetLibParams(env, lib):
  """Gets the params for the given library if it is a library target.

  Returns the params that were specified when the given lib target name was
  created, or None if no such lib target has been defined. In the None case, it
  additionally records the negative result so as to detect out-of-order
  dependencies for future targets.

  Args:
    env: The environment object.
    lib: The library's name as a string.

  Returns:
    Its dictionary of params, or None.
  """
  info = LibraryInfo.get(env)
  if lib in info.lib_targets:
    return info.lib_targets[lib]
  else:
    if lib not in info.prebuilt_libraries and lib not in info.system_libraries:
      info.system_libraries.add(lib)
    return None


def _RecordLibParams(env, lib, params):
  """Record the params used for a library target.

  Record the params used for a library target while checking for several error
  conditions.

  Args:
    env: The environment object.
    lib: The library target's name as a string.
    params: Its dictionary of params.

  Raises:
    Exception: The lib target has already been recorded, or the lib was
        previously declared to be prebuilt, or the lib target is being defined
        after a reverse library dependency.
  """
  info = LibraryInfo.get(env)
  if lib in info.lib_targets:
    raise Exception('Multiple definitions of ' + lib)
  if lib in info.prebuilt_libraries:
    raise Exception(lib + ' already declared as a prebuilt library')
  if lib in info.system_libraries:
    raise Exception(lib + ' cannot be defined after its reverse library '
                    'dependencies')
  info.lib_targets[lib] = params


def _IsPrebuiltLibrary(env, lib):
  """Checks whether or not the given library is a prebuilt static library.

  Returns whether or not the given library name has been declared to be a
  prebuilt static library. In the False case, it additionally records the
  negative result so as to detect out-of-order dependencies for future targets.

  Args:
    env: The environment object.
    lib: The library's name as a string.

  Returns:
    True or False
  """
  info = LibraryInfo.get(env)
  if lib in info.prebuilt_libraries:
    return True
  else:
    if lib not in info.lib_targets and lib not in info.system_libraries:
      info.system_libraries.add(lib)
    return False


def _RecordPrebuiltLibrary(env, lib):
  """Record that a library is a prebuilt static library.

  Record that the given library name refers to a prebuilt static library while
  checking for several error conditions.

  Args:
    env: The environment object.
    lib: The library's name as a string.

  Raises:
    Exception: The lib has already been recorded to be prebuilt, or the lib was
        previously declared as a target, or the lib is being declared as
        prebuilt after a reverse library dependency.
  """
  info = LibraryInfo.get(env)
  if lib in info.prebuilt_libraries:
    raise Exception('Multiple prebuilt declarations of ' + lib)
  if lib in info.lib_targets:
    raise Exception(lib + ' already defined as a target')
  if lib in info.system_libraries:
    raise Exception(lib + ' cannot be declared as prebuilt after its reverse '
                    'library dependencies')
  info.prebuilt_libraries.add(lib)


def _GenericLibrary(env, static, **kwargs):
  """Extends ComponentLibrary to support multiplatform builds
     of dynamic or static libraries.

  Args:
    env: The environment object.
    kwargs: The keyword arguments.

  Returns:
    See swtoolkit ComponentLibrary
  """
  params = CombineDicts(kwargs, {'COMPONENT_STATIC': static})
  return ExtendComponent(env, 'ComponentLibrary', **params)


def DeclarePrebuiltLibraries(env, libraries):
  """Informs the build engine about external static libraries.

  Informs the build engine that the given external library name(s) are prebuilt
  static libraries, as opposed to shared libraries.

  Args:
    env: The environment object.
    libraries: The library or libraries that are being declared as prebuilt
        static libraries.
  """
  if not SCons.Util.is_List(libraries):
    libraries = [libraries]
  for library in libraries:
    _RecordPrebuiltLibrary(env, library)


def Library(env, **kwargs):
  """Extends ComponentLibrary to support multiplatform builds of static
     libraries.

  Args:
    env: The current environment.
    kwargs: The keyword arguments.

  Returns:
    See swtoolkit ComponentLibrary
  """
  return _GenericLibrary(env, True, **kwargs)


def DynamicLibrary(env, **kwargs):
  """Extends ComponentLibrary to support multiplatform builds
     of dynmic libraries.

  Args:
    env: The environment object.
    kwargs: The keyword arguments.

  Returns:
    See swtoolkit ComponentLibrary
  """
  return _GenericLibrary(env, False, **kwargs)


def Object(env, **kwargs):
  return ExtendComponent(env, 'ComponentObject', **kwargs)


def Unittest(env, **kwargs):
  """Extends ComponentTestProgram to support unittest built
     for multiple platforms.

  Args:
    env: The current environment.
    kwargs: The keyword arguments.

  Returns:
    See swtoolkit ComponentProgram.
  """
  kwargs['name'] = kwargs['name'] + '_unittest'

  common_test_params = {
    'posix_cppdefines': ['GUNIT_NO_GOOGLE3', 'GTEST_HAS_RTTI=0'],
    'libs': ['unittest_main', 'gunit']
  }
  if 'explicit_libs' not in kwargs:
    common_test_params['win_libs'] = [
      'advapi32',
      'crypt32',
      'iphlpapi',
      'secur32',
      'shell32',
      'shlwapi',
      'user32',
      'wininet',
      'ws2_32'
    ]
    common_test_params['lin_libs'] = [
      'crypto',
      'pthread',
      'ssl',
    ]

  params = CombineDicts(kwargs, common_test_params)
  return ExtendComponent(env, 'ComponentTestProgram', **params)


def App(env, **kwargs):
  """Extends ComponentProgram to support executables with platform specific
     options.

  Args:
    env: The current environment.
    kwargs: The keyword arguments.

  Returns:
    See swtoolkit ComponentProgram.
  """
  if 'explicit_libs' not in kwargs:
    common_app_params = {
      'win_libs': [
        'advapi32',
        'crypt32',
        'iphlpapi',
        'secur32',
        'shell32',
        'shlwapi',
        'user32',
        'wininet',
        'ws2_32'
      ]}
    params = CombineDicts(kwargs, common_app_params)
  else:
    params = kwargs
  return ExtendComponent(env, 'ComponentProgram', **params)

def WiX(env, **kwargs):
  """ Extends the WiX builder
  Args:
    env: The current environment.
    kwargs: The keyword arguments.

  Returns:
    The node produced by the environment's wix builder
  """
  return ExtendComponent(env, 'WiX', **kwargs)

def Repository(env, at, path):
  """Maps a directory external to $MAIN_DIR to the given path so that sources
     compiled from it end up in the correct place under $OBJ_DIR.  NOT required
     when only referring to header files.

  Args:
    env: The current environment object.
    at: The 'mount point' within the current directory.
    path: Path to the actual directory.
  """
  env.Dir(at).addRepository(env.Dir(path))


def Components(*paths):
  """Completes the directory paths with the correct file
     names such that the directory/directory.scons name
     convention can be used.

  Args:
    paths: The paths to complete. If it refers to an existing
           file then it is ignored.

  Returns:
    The completed lif scons files that are needed to build talk.
  """
  files = []
  for path in paths:
    if os.path.isfile(path):
      files.append(path)
    else:
      files.append(ExpandSconsPath(path))
  return files


def ExpandSconsPath(path):
  """Expands a directory path into the path to the
     scons file that our build uses.
     Ex: magiflute/plugin/common => magicflute/plugin/common/common.scons

  Args:
    path: The directory path to expand.

  Returns:
    The expanded path.
  """
  return '%s/%s.scons' % (path, os.path.basename(path))


def ReadVersion(filename):
  """Executes the supplied file and pulls out a version definition from it. """
  defs = {}
  execfile(str(filename), defs)
  if 'version' not in defs:
    return '0.0.0.0'
  version = defs['version']
  parts = version.split(',')
  build = os.environ.get('GOOGLE_VERSION_BUILDNUMBER')
  if build:
    parts[-1] = str(build)
  return '.'.join(parts)


#-------------------------------------------------------------------------------
# Helper methods for translating talk.Foo() declarations in to manipulations of
# environmuent construction variables, including parameter parsing and merging,
#
def PopEntry(dictionary, key):
  """Get the value from a dictionary by key. If the key
     isn't in the dictionary then None is returned. If it is in
     the dictionary the value is fetched and then is it removed
     from the dictionary.

  Args:
    dictionary: The dictionary.
    key: The key to get the value for.
  Returns:
    The value or None if the key is missing.
  """
  value = None
  if key in dictionary:
    value = dictionary[key]
    dictionary.pop(key)
  return value


def MergeAndFilterByPlatform(env, params):
  """Take a dictionary of arguments to lists of values, and, depending on
     which platform we are targetting, merge the lists of associated keys.
     Merge by combining value lists like so:
       {win_foo = [a,b], lin_foo = [c,d], foo = [e], mac_bar = [f], bar = [g] }
       becomes {foo = [a,b,e], bar = [g]} on windows, and
       {foo = [e], bar = [f,g]} on mac

  Args:
    env: The hammer environment which knows which platforms are active
    params: The keyword argument dictionary.
  Returns:
    A new dictionary with the filtered and combined entries of params
  """
  platforms = {
    'linux': 'lin_',
    'mac': 'mac_',
    'posix': 'posix_',
    'windows': 'win_',
  }
  active_prefixes = [
    platforms[x] for x in iter(platforms) if env.Bit(x)
  ]
  inactive_prefixes = [
    platforms[x] for x in iter(platforms) if not env.Bit(x)
  ]

  merged = {}
  for arg, values in params.iteritems():
    inactive_platform = False

    key = arg

    for prefix in active_prefixes:
      if arg.startswith(prefix):
        key = arg[len(prefix):]

    for prefix in inactive_prefixes:
      if arg.startswith(prefix):
        inactive_platform = True

    if inactive_platform:
      continue

    AddToDict(merged, key, values)

  return merged


# Whether to enable extra 64-bit targets marked with the also64bit setting. Used
# only for the legacy mixed 32/64 desktop Linux build.
def EnableExtra64BitTargets(env):
  return (env.Bit('linux') and env.Bit('build_platform_64bit') and
          not env.Bit('host_platform_64bit') and
          not env.Bit('host_platform_mipsel')
          )


def MergeSettingsFromLibraryDependencies(env, params):
  if 'libs' in params:
    for lib in params['libs']:
      libparams = _GetLibParams(env, lib)
      if libparams:
        if 'dependent_target_settings' in libparams:
          params = CombineDicts(
              params,
              MergeAndFilterByPlatform(
                  env,
                  libparams['dependent_target_settings']))
  return params


def ExtendComponent(env, component, **kwargs):
  """A wrapper around a scons builder function that preprocesses and post-
     processes its inputs and outputs.  For example, it merges and filters
     certain keyword arguments before appending them to the environments
     construction variables.  It can build signed targets and 64bit copies
     of targets as well.

  Args:
    env: The hammer environment with which to build the target
    component: The environment's builder function, e.g. ComponentProgram
    kwargs: keyword arguments that are either merged, translated, and passed on
            to the call to component, or which control execution.
            TODO(): Document the fields, such as cppdefines->CPPDEFINES,
            prepend_includedirs, include_talk_media_libs, etc.
  Returns:
    The output node returned by the call to component, or a subsequent signed
    dependant node.
  """
  env = env.Clone()

  # prune parameters intended for other platforms, then merge
  params = MergeAndFilterByPlatform(env, kwargs)

  # get the 'target' field
  name = PopEntry(params, 'name')

  # get the 'packages' field and process it if present (only used for Linux).
  packages = PopEntry(params, 'packages')
  if packages and len(packages):
    params = CombineDicts(params, env.GetPackageParams(packages))

  # save pristine params of lib targets for future reference
  if 'ComponentLibrary' == component:
    _RecordLibParams(env, name, dict(params))

  # add any dependent target settings from library dependencies
  params = MergeSettingsFromLibraryDependencies(env, params)

  # if this is a signed binary we need to make an unsigned version first
  signed = env.Bit('windows') and PopEntry(params, 'signed')
  if signed:
    name = 'unsigned_' + name

  # potentially exit now
  srcs = PopEntry(params, 'srcs')
  if not srcs or not hasattr(env, component):
    return None

  # apply any explicit dependencies
  dependencies = PopEntry(params, 'depends')
  if dependencies is not None:
    env.Depends(name, dependencies)

  # put the contents of params into the environment
  # some entries are renamed then appended, others renamed then prepended
  appends = {
    'cppdefines' : 'CPPDEFINES',
    'libdirs' : 'LIBPATH',
    'link_flags' : 'LINKFLAGS',
    'libs' : 'LIBS',
    'FRAMEWORKS' : 'FRAMEWORKS',
  }
  prepends = {}
  if env.Bit('windows'):
    # MSVC compile flags have precedence at the beginning ...
    prepends['ccflags'] = 'CCFLAGS'
  else:
    # ... while GCC compile flags have precedence at the end
    appends['ccflags'] = 'CCFLAGS'
  if PopEntry(params, 'prepend_includedirs'):
    prepends['includedirs'] = 'CPPPATH'
  else:
    appends['includedirs'] = 'CPPPATH'

  for field, var in appends.items():
    values = PopEntry(params, field)
    if values is not None:
      env.Append(**{var : values})
  for field, var in prepends.items():
    values = PopEntry(params, field)
    if values is not None:
      env.Prepend(**{var : values})

  # workaround for pulse stripping link flag for unknown reason
  if EnableExtra64BitTargets(env):
    env['SHLINKCOM'] = ('$SHLINK -o $TARGET -m32 $SHLINKFLAGS $SOURCES '
                        '$_LIBDIRFLAGS $_LIBFLAGS')
    env['LINKCOM'] = ('$LINK -o $TARGET -m32 $LINKFLAGS $SOURCES '
                      '$_LIBDIRFLAGS $_LIBFLAGS')

  # any other parameters are replaced without renaming
  for field, value in params.items():
    env.Replace(**{field : value})

  if env.Bit('linux') and 'LIBS' in env:
    libs = env['LIBS']
    # When using --as-needed + --start/end-group, shared libraries need to come
    # after --end-group on the command-line because the pruning decision only
    # considers the preceding modules and --start/end-group may cause the
    # effective position of early static libraries on the command-line to be
    # deferred to the point of --end-group. To effect this, we move shared libs
    # into _LIBFLAGS, which has the --end-group as its first entry. SCons does
    # not track dependencies on system shared libraries anyway so we lose
    # nothing by removing them from LIBS.
    static_libs = [lib for lib in libs if
                   _GetLibParams(env, lib) or _IsPrebuiltLibrary(env, lib)]
    shared_libs = ['-l' + lib for lib in libs if not
                   (_GetLibParams(env, lib) or _IsPrebuiltLibrary(env, lib))]
    env.Replace(LIBS=static_libs)
    env.Append(_LIBFLAGS=shared_libs)

  # invoke the builder function
  builder = getattr(env, component)

  node = builder(name, srcs)

  # make a parallel 64bit version if requested
  if EnableExtra64BitTargets(env) and PopEntry(params, 'also64bit'):
    env_64bit = env.Clone()
    env_64bit.FilterOut(CCFLAGS = ['-m32'], LINKFLAGS = ['-m32'])
    env_64bit.Prepend(CCFLAGS = ['-m64', '-fPIC'], LINKFLAGS = ['-m64'])
    name_64bit = name + '64'
    env_64bit.Replace(OBJSUFFIX = '64' + env_64bit['OBJSUFFIX'])
    env_64bit.Replace(SHOBJSUFFIX = '64' + env_64bit['SHOBJSUFFIX'])
    if ('ComponentProgram' == component or
        ('ComponentLibrary' == component and
         env_64bit['COMPONENT_STATIC'] == False)):
      # link 64 bit versions of libraries
      libs = []
      for lib in env_64bit['LIBS']:
        libparams = _GetLibParams(env, lib)
        if libparams and 'also64bit' in libparams:
          libs.append(lib + '64')
        else:
          libs.append(lib)
      env_64bit.Replace(LIBS = libs)

    env_64bit['SHLINKCOM'] = ('$SHLINK -o $TARGET -m64 $SHLINKFLAGS $SOURCES '
                              '$_LIBDIRFLAGS $_LIBFLAGS')
    env_64bit['LINKCOM'] = ('$LINK -o $TARGET -m64 $LINKFLAGS $SOURCES '
                            '$_LIBDIRFLAGS $_LIBFLAGS')
    builder = getattr(env_64bit, component)
    nodes = [node, builder(name_64bit, srcs)]
    return nodes

  if signed:  # Note currently incompatible with 64Bit flag
    # Get the name of the built binary, then get the name of the final signed
    # version from it.  We need the output path since we don't know the file
    # extension beforehand.
    target = node[0].path.split('_', 1)[1]
    # postsignprefix: If defined, postsignprefix is a string that should be
    # prepended to the target executable.  This is to provide a work around
    # for EXEs and DLLs with the same name, which thus have PDBs with the
    # same name.  Setting postsignprefix allows the EXE and its PDB
    # to be renamed and copied in a previous step; then the desired
    # name of the EXE (but not PDB) is reconstructed after signing.
    postsignprefix = PopEntry(params, 'postsignprefix')
    if postsignprefix is not None:
        target = postsignprefix + target
    signed_node = env.SignedBinary(
      source = node,
      target = '$STAGING_DIR/' + target,
    )
    env.Alias('signed_binaries', signed_node)
    return signed_node

  return node


def AddToDict(dictionary, key, values, append=True):
  """Merge the given key value(s) pair into a dictionary.  If it contains an
     entry with that key already, then combine by appending or prepending the
     values as directed.  Otherwise, assign a new keyvalue pair.
  """
  if values is None:
    return

  if key not in dictionary:
    dictionary[key] = values
    return

  cur = dictionary[key]
  # TODO: Make sure that there are no duplicates
  # in the list. I can't use python set for this since
  # the nodes that are returned by the SCONS builders
  # are not hashable.
  # dictionary[key] = list(set(cur).union(set(values)))
  if append:
    dictionary[key] = cur + values
  else:
    dictionary[key] = values + cur


def CombineDicts(a, b):
  """Unions two dictionaries of arrays/dictionaries.

  Unions two dictionaries of arrays/dictionaries by combining the values of keys
  shared between them. The original dictionaries should not be used again after
  this call.

  Args:
    a: First dict.
    b: Second dict.

  Returns:
    The union of a and b.
  """
  c = {}
  for key in a:
    if key in b:
      aval = a[key]
      bval = b.pop(key)
      if isinstance(aval, dict) and isinstance(bval, dict):
        c[key] = CombineDicts(aval, bval)
      else:
        c[key] = aval + bval
    else:
      c[key] = a[key]

  for key in b:
    c[key] = b[key]

  return c


def RenameKey(d, old, new, append=True):
  AddToDict(d, new, PopEntry(d, old), append)
