# Copyright (c) 2008 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.

import fnmatch
import os
import re
import shutil
import subprocess
import utils
import SCons.Node

Import('env')

env = env.Clone()

if env['OS'] in ['win32', 'wince']:
  env.Append(DATE = 'echo %DATE%.%TIME%')
else:
  env.Append(DATE = 'date')

def GetInputs(var): return utils.GetInputs(var, env)

def Shell(cmd):
  """Execute a shell command and return the output."""
  cmd[0] = env.Entry(cmd[0]).abspath
  cmd = env.subst(cmd)
  return subprocess.Popen(
      cmd, shell=True, stdout=subprocess.PIPE).communicate()[0]

if env['OS'] == 'win32':
  def GGUIDGen(value):
    """Generate a GGUID for the given value."""
    return Shell(['$GGUIDGEN', '$NAMESPACE_GUID', value + '-$VERSION'])
  env.Replace(
      GGUIDGEN = '#/$OPEN_DIR/tools/gguidgen.exe',
      NAMESPACE_GUID = '36F65206-5D4E-4752-9D52-27708E10DA79',
# MSI version numbers must have the form <major>.<minor>.<build>. To meet this,
# we combine our build and patch version numbers like so:
# MSI_VERSION = <major>.<minor>.<BUILD * 100 + PATCH>.
# Note: This assumes that the BUILD and PATCH variables adhere to the range
# requirements in version.mk. See comments in version.mk for more details.
      MSI_BUILD = eval(env.subst('$BUILD * 100 + $PATCH')),
      MSI_VERSION = '${MAJOR}.${MINOR}.${MSI_BUILD}',
  )

  # Building wxiobjs with candle
  env.Replace(
      CANDLEDEFPREFIX = '-d',
      CANDLEDEFSUFFIX = '',
      _CANDLEDEFFLAGS = ('${_defines(CANDLEDEFPREFIX, CANDLEDEFINES, '
                         'CANDLEDEFSUFFIX, __env__)}'),
      CANDLECOM = 'candle.exe -out $TARGET $SOURCE ${_CANDLEDEFFLAGS}',
  )
  env.Append(
# Note: Since light.exe is run from $OPEN_DIR, candle.exe must generate
# output with paths relative to that dir.
      SCONS_DIR = '..',  # the scons dir relative to OPEN_DIR
# You can change the names of ProductId vars, but NEVER change their values!
      CANDLEDEFINES = [
          ('OurWin32ProductId',
            GGUIDGen('OUR_PRODUCT_ID')),
          ('OurComponentGUID_FFComponentsDirFiles',
            GGUIDGen('OUR_COMPONENT_GUID_FF_COMPONENTS_DIR_FILES')),
          ('OurComponentGUID_FFContentDirFiles',
            GGUIDGen('OUR_COMPONENT_GUID_FF_CONTENT_DIR_FILES')),
          ('OurComponentGUID_FFDirFiles',
            GGUIDGen('OUR_COMPONENT_GUID_FF_DIR_FILES')),
          ('OurComponentGUID_FFLibDirFiles',
            GGUIDGen('OUR_COMPONENT_GUID_FF_LIB_DIR_FILES')),
          ('OurComponentGUID_FFRegistry',
            GGUIDGen('OUR_COMPONENT_GUID_FF_REGISTRY')),
          ('OurComponentGUID_IEFiles',
            GGUIDGen('OUR_COMPONENT_GUID_IE_FILES')),
          ('OurComponentGUID_IERegistry',
            GGUIDGen('OUR_COMPONENT_GUID_IE_REGISTRY')),
          ('OurComponentGUID_SharedFiles',
            GGUIDGen('OUR_COMPONENT_GUID_SHARED_FILES')),
          ('OurComponentGUID_SharedVersionedFiles',
            GGUIDGen('OUR_COMPONENT_GUID_SHARED_VERSIONED_FILES')),
          ('OurComponentGUID_SharedRegistry',
            GGUIDGen('OUR_COMPONENT_GUID_SHARED_REGISTRY')),
          ('OurNpapiProductId',
            GGUIDGen('OUR_2ND_PRODUCT_ID')),
          ('OurComponentGUID_NpapiFiles',
            GGUIDGen('OUR_COMPONENT_GUID_NPAPI_FILES')),
          ('OurComponentGUID_NpapiRegistry',
            GGUIDGen('OUR_COMPONENT_GUID_NPAPI_REGISTRY')),
          ('OurMsiVersion', '$MSI_VERSION'),
          ('OurCommonPath', '$COMMON_OUTDIR'),
          ('OurIEPath', '$IE_OUTDIR'),
          ('OurIpcTestPath', '$COMMON_OUTDIR'),
          ('OurFFPath', '$INSTALLER_OUTDIR/$INSTALLER_BASENAME'),
          ('OurNpapiPath', '$NPAPI_OUTDIR'),
      ]
  )
  wix_langs = [re.sub('-', '_', lang) for lang in env['I18N_LANGS']]
  env.Append(
      CANDLEDEFINES =
        [('OurComponentGUID_FFLang' + lang + 'DirFiles',
           GGUIDGen('OUR_COMPONENT_GUID_FF_' + lang + '_DIR_FILES'))
         for lang in wix_langs],
  )

def SafeMkdir(dir):
  """Like the builtin Mkdir, but doesn't fail if the dir exists."""
  def Func(target, source, env):
    dir_subst = env.subst(dir, target=target)
    if not os.path.exists(dir_subst):
      os.makedirs(dir_subst)
    return 0
  return Action(Func, 'SafeMkdir("' + dir + '")')

def RecursiveDelete(pattern):
  """Recursively deletes directories matching a pattern."""
  def Func(target, source, env):
    # strip off '.dir' suffix
    target_dir = env.subst('${TARGET.base}', target=target)
    for root, dirs, files in os.walk(target_dir):
      if fnmatch.fnmatch(os.path.normpath(root), pattern):
        print 'Deleting', root
        shutil.rmtree(root)
    return 0
  return Action(Func, 'RecursiveDelete("' + pattern + '")')

def ToUnixPath(path):
  """Converts windows-style \ to unix-style /."""
  return re.sub(r'\\', r'/', path)

def DirBuilder(env, dirtarget, dirsrcs):
  """Builder that makes a directory tree by copying source files to
  corresponding locations inside 'dirtarget'.  'dirsrcs' specifies the list of
  mappings from source file/directory to the target location.  It's formatted
  like:
    (<target file or dir>, <list of source files>)

  Note: source files that come from an output directory must be explicitly
  specified relative to the toplevel dir '#'.
  Note: as shorthand, if the target ends with a '/', then the sources will
  be placed into that dir.  Otherwise, source is renamed into the target.
  """

  srcs = []
  actions = [Delete('${TARGET.base}')]
  for target, sources in dirsrcs:
    target_is_dir = target.endswith('/')
    if target_is_dir:
      actions.append(SafeMkdir('${TARGET.base}/' + target))
    else:
      actions.append(SafeMkdir('${TARGET.base}/' + os.path.dirname(target)))
    for source in env.Flatten(sources):
      source = env.subst(source, conv=lambda x:x)
      srcs.append(source)

      # Special-case for Nodes and Node lists: use their absolute paths for
      # the Copy() action, otherwise it will be relative to our variant dir
      # (not what Copy expects).
      if isinstance(source, list): source = source[0]
      if isinstance(source, SCons.Node.Node): source = source.abspath

      # HACK: Compensate for the workaround below.  We want the .dir file
      # to be the dependency to the Command() builder, but we want to copy
      # the actual directory - so strip the extension here.
      if source.endswith('.dir'):
        source = source[:-4]

      if target_is_dir:
        actions.append(
            Copy('${TARGET.base}/' + target + os.path.basename(source),
                 source))
      else:
        actions.append(Copy('${TARGET.base}/' + target, source))

  # Remove any .svn directories that were copied.
  actions.append(RecursiveDelete('*/.svn'))

  # HACK: Workaround for bug in scons where directories aren't checked for
  # dependency changes.  Instead, we make a temp file the target, and ensure
  # that that file changes everytime we execute these actions.
  # See http://scons.tigris.org/issues/show_bug.cgi?id=2261
  actions += ['$DATE > ${TARGET}']
  return env.Command(env.subst(dirtarget) + '.dir', srcs, actions)
env.AddMethod(DirBuilder)

def FirefoxInstaller():
  dirsrcs = [
      ('/', ['$FF3_OUTDIR/genfiles/install.rdf',
             '$FF3_OUTDIR/genfiles/chrome.manifest']),
      ('lib/', ['$OPEN_DIR/base/firefox/static_files/lib/updater.js']),
      ('chrome/chromeFiles/content/',
          GetInputs('$FF3_RESOURCES $COMMON_RESOURCES')),
      ('chrome/chromeFiles/locale', ['$FF3_OUTDIR/genfiles/i18n']),
      ('components/',
          ['$FF3_MODULE_TYPELIB',
           '$OPEN_DIR/base/firefox/static_files/components/bootstrap.js']),
      ('components/${SHLIBPREFIX}gears${SHLIBSUFFIX}', ['$FF2_MODULE']),
      ('components/${SHLIBPREFIX}gears_ff2${SHLIBSUFFIX}', ['$FF3_MODULE']),
  ]

  if env['USING_CCTESTS']:
    dirsrcs += [
        ('components/', ['$IPC_TEST_EXE']),
    ]
  if env['OS'] != 'win32':
    # TODO(playmobil): Inspector should be located in extensions dir on win32.
    dirsrcs += [
        ('resources/inspector', [env.Dir('#/$OPEN_DIR/inspector')]),
        ('resources/inspector/common/', ['$OPEN_DIR/sdk/gears_init.js',
                                         '$OPEN_DIR/sdk/samples/sample.js']),
    ]
  if env['MODE'] == 'dbg' and env['OS'] in ['win32', 'wince']:
    dirsrcs += [
        ('components/gears_ff2.pdb', ['$FF2_MODULE_PDB']),
        ('components/gears.pdb', ['$FF3_MODULE_PDB']),
    ]
  if env['OS'] == 'osx':
    dirsrcs += [
        ('resources/', ['$OSX_LAUNCHURL_EXE']),
    ]

  dir = env.DirBuilder('$INSTALLER_OUTDIR/$INSTALLER_BASENAME', dirsrcs)
  actions = [
      # Mark files writeable to allow .xpi rebuilds
      'chmod -R 777 ${SOURCE.base}',
      '(cd ${SOURCE.base} && zip -r ../${TARGET.file} .)'
  ]

  return env.Command('$FF_XPI', dir, actions)
firefox_installer = FirefoxInstaller()

def Win32Installer():
  wxiobj = env.Command(
      '$COMMON_GENFILES_DIR/win32_msi.wxiobj',
      '$COMMON_GENFILES_DIR/win32_msi.wxs',
      '$CANDLECOM')
  # TODO(mpcomplete): remove this if/when the notifier goes away.  This
  # creates fake targets to satisfy the installer build.
  notifier = env.Command(
      [
          '$COMMON_OUTDIR/notifier.exe',
          '$COMMON_OUTDIR/notifier.dll',
          '$COMMON_OUTDIR/notifier_test.exe'
      ], [],
      'touch $TARGETS')
  # light.exe must be run from $OPEN_DIR
  msi = env.Command(
      '$WIN32_INSTALLER_MSI',
      [wxiobj, notifier, firefox_installer, '$IE_MODULE', '$NPAPI_MODULE'],
      'cd $OPEN_DIR && light.exe -out ${TARGET.abspath} ${SOURCES[0].abspath}')
  return msi
win32_installer = Win32Installer()

def WinCEInstaller():
  env['ToUnixPath'] = ToUnixPath
  inf_outdir = ToUnixPath(env.subst('$IE_OUTDIR'))
  inf = env.Command(
      '$COMMON_GENFILES_DIR/wince_cab_fixed.inf',
      '$COMMON_GENFILES_DIR/wince_cab_ie.inf',
      'sed -e "s#bin-....wince-arm.ie.#' + inf_outdir + '#g" $SOURCE > $TARGET')
  cab = env.Command(
      '$WINCE_INSTALLER_CAB',
      [inf, '$IE_MODULE', '$IE_WINCE_SETUP_DLL'],
      ['cabwiz ${ToUnixPath(str(SOURCE))} /compress'
       ' /err ${SOURCES[0].base}.log',
       Copy('$TARGET', '${SOURCE.base}.CAB')])
  return cab
wince_installer = WinCEInstaller()

def SafariPluginBundle():
  """This is the actual gears plugin bundle for Safari."""
  dirsrcs = [
      ('Contents/', ['$SF_OUTDIR/genfiles/Info.plist']),
      ('Contents/Resources/English.lproj/InfoPlist.strings',
          ['$OPEN_DIR/tools/osx/English.lproj/InfoPlist.strings']),
      ('Contents/Resources/', env.Glob('#/$OPEN_DIR/ui/safari/*.nib')),
      ('Contents/Resources/', ['$CRASH_SENDER_EXE']),
      ('Contents/Resources/', ['$OSX_CRASH_INSPECTOR_EXE']),
      ('Contents/Resources/', ['$OSX_LAUNCHURL_EXE']),
      ('Contents/MacOS/', ['$SF_MODULE']), 
  ]

  if env['USING_CCTESTS']:
    dirsrcs += [
        ('Contents/Resources/', ['$IPC_TEST_EXE']),
    ]

  return env.DirBuilder('$SF_PLUGIN_BUNDLE', dirsrcs)
safari_plugin_bundle = SafariPluginBundle()

def SafariPluginProxyBundle():
  """This is a proxy plugin which simply loads gears into Safari and keeps
  it in memory. It exists so that gears doesn't unload when Safari wants us
  to, since that causes crashes."""
  dirsrcs = [
      ('Contents/', ['$SF_OUTDIR/genfiles/Info.plist']),
      ('Contents/MacOS/${SHLIBPREFIX}gears${SHLIBSUFFIX}', ['$SF_PROXY_DLL']),
      ('Contents/Resources/', [safari_plugin_bundle]),
      ('Contents/Resources/', ['$OPEN_DIR/tools/osx/uninstall.command']),
  ]

  return env.DirBuilder('$SF_PLUGIN_PROXY_BUNDLE', dirsrcs)
safari_plugin_proxy_bundle = SafariPluginProxyBundle()

def SafariInstallerPluginBundle():
  dirsrcs = [
      ('Contents/Info.plist',
          ['$OPEN_DIR/base/safari/advanced_stats_sheet.plist']),
      ('Contents/MacOS/InstallerPlugin', ['$SF_INSTALLER_PLUGIN_EXE']),
      ('Contents/Resources/AdvancedStatsSheet.nib',
          [env.Dir('#/$OPEN_DIR/base/safari/advanced_stats_sheet.nib')]),
  ]

  return env.DirBuilder('$SF_INSTALLER_PLUGIN_BUNDLE', dirsrcs)
safari_installer_plugin_bundle = SafariInstallerPluginBundle()

def SafariInputManagerBundle():
  info = env.Command('$SF_OUTDIR/genfiles/Enabler-Info.plist',
      '$OPEN_DIR/tools/osx/Enabler-Info.plist',
      'cat $SOURCE |'
      'sed \'s/$${EXECUTABLE_NAME}/GearsEnabler/\' |'
      'sed \'s/$${PRODUCT_NAME}/GearsEnabler/\' > $TARGET')
  dirsrcs = [
      ('GearsEnabler.bundle/Contents/Info.plist', [info]),
      ('GearsEnabler.bundle/Contents/MacOS/', ['$SF_INPUTMANAGER_EXE']),
      ('GearsEnabler.bundle/Contents/Resources/English.lproj/',
          ['$OPEN_DIR/tools/osx/English.lproj/InfoPlist.strings']),
      ('Info', ['$OPEN_DIR/tools/osx/Info']),
  ]

  return env.DirBuilder('$SF_INPUTMANAGER_BUNDLE', dirsrcs)
safari_input_manager_bundle = SafariInputManagerBundle()

def SafariInstallerPackage():
  pkg = env.Iceberg(env.Dir('${SF_INSTALLER_PKG}'),
      [
          '$SF_OUTDIR/genfiles/installer.packproj',
          safari_plugin_proxy_bundle,
          safari_input_manager_bundle,
      ])
  return pkg
safari_installer_package = SafariInstallerPackage()

def SafariKeystoneInstaller():
  if not os.path.exists(env.Dir('#/$PRIVATE_DIR').abspath):
    print 'Skipping Safari Keystone installer. Required sources are not public.'
    return []

  env.Append(CREATE_DISK_IMAGE =
      "/usr/bin/hdiutil create -ov -imagekey zlib-level=9 -fs HFS+"
      " -format UDZO -volname '$FRIENDLY_NAME ${VERSION}'"
      " -srcfolder '${INSTALLER_OUTDIR}/Safari/dmg/' -scrub"
      " -nocrossdev '${SF_KEYSTONE_INSTALLER_DMG}'"
  )

  pkg = env.Iceberg(env.Dir('${SF_KEYSTONE_INSTALLER_MPKG}'),
      ['$SF_OUTDIR/genfiles/keystone_installer.packproj'])
  env.Depends(pkg, GetInputs('$SF_M4S'))
  env.Depends(pkg, safari_installer_package)

  dirsrcs = [
      ('/', [pkg]),
      ('/.keystone_install',
          ['$PRIVATE_DIR/tools/osx/installer/keystone_install']),
  ]
  dmg = env.DirBuilder('$INSTALLER_OUTDIR/Safari/dmg', dirsrcs)
  env.AddPostAction(dmg, 'chmod +x ${TARGET.base}/.keystone_install')
  # hdiutil is crashy under leopard, so try twice.
  env.AddPostAction(dmg, '$CREATE_DISK_IMAGE || $CREATE_DISK_IMAGE')

  return dmg
safari_keystone_installer = SafariKeystoneInstaller()

installers = []
if 'FF3' in env['VALID_BROWSERS']:
  installers += firefox_installer
if 'SF' in env['VALID_BROWSERS']:
  installers += [
      safari_input_manager_bundle,
      safari_plugin_bundle,
      safari_plugin_proxy_bundle,
      safari_installer_plugin_bundle,
      safari_installer_package,
      safari_input_manager_bundle,
      safari_keystone_installer,
  ]
if env['OS'] == 'win32':
  installers += win32_installer
if env['OS'] == 'wince':
  installers += wince_installer

env.Alias('gears-installers', installers)
