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

# Keep a global dictionary of library target params for lookups in
# ExtendComponent().
_all_lib_targets = {}
# Maintain a set of all prebuilt static libraries.
_all_prebuilt_libraries = set()
# Set of libraries not found in the above (used to detect out-of-order build
# rules).
_all_system_libraries = set()

def _GetLibParams(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:
    lib: The library's name as a string.

  Returns:
    Its dictionary of params, or None.
  """
  if lib in _all_lib_targets:
    return _all_lib_targets[lib]
  else:
    if lib not in _all_prebuilt_libraries and lib not in _all_system_libraries:
      _all_system_libraries.add(lib)
    return None


def _RecordLibParams(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:
    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.
  """
  if lib in _all_lib_targets:
    raise Exception('Multiple definitions of ' + lib)
  if lib in _all_prebuilt_libraries:
    raise Exception(lib + ' already declared as a prebuilt library')
  if lib in _all_system_libraries:
    raise Exception(lib + ' cannot be defined after its reverse library '
                    'dependencies')
  _all_lib_targets[lib] = params


def _IsPrebuiltLibrary(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:
    lib: The library's name as a string.

  Returns:
    True or False
  """
  if lib in _all_prebuilt_libraries:
    return True
  else:
    if lib not in _all_lib_targets and lib not in _all_system_libraries:
      _all_system_libraries.add(lib)
    return False


def _RecordPrebuiltLibrary(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:
    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.
  """
  if lib in _all_prebuilt_libraries:
    raise Exception('Multiple prebuilt declarations of ' + lib)
  if lib in _all_lib_targets:
    raise Exception(lib + ' already defined as a target')
  if lib in _all_system_libraries:
    raise Exception(lib + ' cannot be declared as prebuilt after its reverse '
                    'library dependencies')
  _all_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(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:
    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(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


# Linux can build both 32 and 64 bit on 64 bit host, but 32 bit host can
# only build 32 bit.  For 32 bit debian installer a 32 bit host is required.
# ChromeOS (linux) ebuild don't support 64 bit and requires 32 bit build only
# for now.
def Allow64BitCompile(env):
  return (env.Bit('linux') and env.Bit('platform_arch_64bit')
          )


def MergeSettingsFromLibraryDependencies(env, params):
  if 'libs' in params:
    for lib in params['libs']:
      libparams = _GetLibParams(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(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 Allow64BitCompile(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(lib) or _IsPrebuiltLibrary(lib)]
    shared_libs = ['-l' + lib for lib in libs if not
                   (_GetLibParams(lib) or _IsPrebuiltLibrary(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 Allow64BitCompile(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(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)
