#!/usr/bin/python

# Copyright (c) 2011 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 glob
import optparse
import os
import shutil
import sys
import utils

HOST_OS = utils.guessOS()

if HOST_OS == 'mac':
  CONTENTSHELL_FILES = ['Content Shell.app', 'ffmpegsumo.so', 'osmesa.so',
                        'lib']
  CHROMEDRIVER_FILES = ['chromedriver']
elif HOST_OS == 'linux':
  CONTENTSHELL_FILES = ['content_shell', 'content_shell.pak', 'fonts.conf',
                        'libffmpegsumo.so', 'libosmesa.so', 'lib',
                        'icudtl.dat', 'AHEM____.TTF', 'GardinerModBug.ttf',
                        'GardinerModCat.ttf', 'natives_blob.bin']
  CHROMEDRIVER_FILES = ['chromedriver']
elif HOST_OS == 'win':
  # TODO: provide proper list.
  CONTENTSHELL_FILES = ['content_shell.exe', 'AHEM____.ttf', 'icudtl.dat', ]
  CHROMEDRIVER_FILES = ['chromedriver.exe']
else:
  raise Exception('Unsupported platform')

# Append a file with size of the snapshot.
CONTENTSHELL_FILES.append('snapshot-size.txt')


def GenerateDartiumFileList(mode, srcpath):
  def blacklisted(name):
    # We include everything if this is a debug build.
    if mode.lower() == 'debug':
      return True
    else:
      # We don't include .debug/.pdb files if this is a release build.
      if name.endswith('.debug') or name.endswith('.pdb'):
        return False
      return True

  configFile = os.path.join(srcpath, 'chrome', 'tools', 'build', HOST_OS,
                            'FILES.cfg')
  configNamespace = {}
  execfile(configFile, configNamespace)
  fileList = [file['filename'] for file in configNamespace['FILES']]

  # The debug version of dartium on our bots build with
  # 'component=shared_library', so we need to include all libraries
  # (i.e. 'lib/*.so) as we do on the CONTENTSHELL_FILES list above.
  if HOST_OS == 'linux' and mode.lower() == 'debug':
    fileList.append('lib')

  # Filter out files we've blacklisted and don't want to include.
  fileList = filter(blacklisted, fileList)
  return fileList


def GenerateContentShellFileList(srcpath):
  return CONTENTSHELL_FILES


def GenerateChromeDriverFileList(srcpath):
  return CHROMEDRIVER_FILES


def ZipDir(zipFile, directory):
  if HOST_OS == 'win':
    cmd = os.path.normpath(os.path.join(
        os.path.dirname(__file__),
        '../../../third_party/lzma_sdk/Executable/7za.exe'))
    options = ['a', '-r', '-tzip']
  else:
    cmd = 'zip'
    options = ['-yr']
  utils.runCommand([cmd] + options + [zipFile, directory])


def GenerateZipFile(zipFile, stageDir, fileList):
  # Stage files.
  for fileName in fileList:
    fileName = fileName.rstrip(os.linesep)
    targetName = os.path.join(stageDir, fileName)
    try:
      targetDir = os.path.dirname(targetName)
      if not os.path.exists(targetDir):
        os.makedirs(targetDir)
      if os.path.isdir(fileName):
        # TODO: This is a hack to handle duplicates on the fileList of the
        # form: [ 'lib/foo.so', 'lib' ]
        if os.path.exists(targetName) and os.path.isdir(targetName):
          shutil.rmtree(targetName)
        shutil.copytree(fileName, targetName)
      elif os.path.exists(fileName):
        shutil.copy2(fileName, targetName)
    except:
      import traceback
      print 'Troubles processing %s [cwd=%s]: %s' % (fileName, os.getcwd(), traceback.format_exc())

  ZipDir(zipFile, stageDir)


def StageAndZip(fileList, target):
  if not target:
    return None

  stageDir = target
  zipFile = stageDir + '.zip'

  # Cleanup old files.
  if os.path.exists(stageDir):
    shutil.rmtree(stageDir)
  os.mkdir(stageDir)
  revision = target.split('-')[-1]
  oldFiles = glob.glob(target.replace(revision, '*.zip'))
  for oldFile in oldFiles:
    os.remove(oldFile)

  GenerateZipFile(zipFile, stageDir, fileList)
  print 'last change: %s' % (zipFile)

  # Clean up. Buildbot disk space is limited.
  shutil.rmtree(stageDir)

  return zipFile


def Archive(srcpath, mode, dartium_target, contentshell_target,
            chromedriver_target):
  # We currently build using ninja on mac debug.
  if HOST_OS == 'mac':
    releaseDir = os.path.join(srcpath, 'out', mode)
    # Also package dynamic libraries.
    extra_files = [file for file in os.listdir(releaseDir) if file.endswith('.dylib')]
  elif HOST_OS == 'linux':
    releaseDir = os.path.join(srcpath, 'out', mode)
    extra_files = []
  elif HOST_OS == 'win':
    releaseDir = os.path.join(srcpath, 'out', mode)
    # issue(16760) - we _need_ to fix our parsing of the FILES.cfg
    extra_files = [file for file in os.listdir(releaseDir) if file.endswith('manifest')]
  else:
    raise Exception('Unsupported platform')
  os.chdir(releaseDir)

  dartium_zip = StageAndZip(
      GenerateDartiumFileList(mode, srcpath) + extra_files, dartium_target)
  contentshell_zip = StageAndZip(GenerateContentShellFileList(srcpath) + extra_files,
                                 contentshell_target)
  chromedriver_zip = StageAndZip(GenerateChromeDriverFileList(srcpath) + extra_files,
                                 chromedriver_target)
  return (dartium_zip, contentshell_zip, chromedriver_zip)


def main():
  pathname = os.path.dirname(sys.argv[0])
  fullpath = os.path.abspath(pathname)
  srcpath = os.path.join(fullpath, '..', '..', '..')

  parser = optparse.OptionParser()
  parser.add_option('--dartium', dest='dartium',
                    action='store', type='string',
                    help='dartium archive name')
  parser.add_option('--contentshell', dest='contentshell',
                    action='store', type='string',
                    help='content shell archive name')
  parser.add_option('--chromedriver', dest='chromedriver',
                    action='store', type='string',
                    help='chromedriver archive name')
  parser.add_option('--mode', dest='mode',
                    default='Release',
                    action='store', type='string',
                    help='(Release|Debug)')
  (options, args) = parser.parse_args()
  Archive(srcpath, options.mode, options.dartium, options.contentshell,
          options.chromedriver)
  return 0


if __name__ == '__main__':
  sys.exit(main())
