#!/usr/bin/python
# Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

import optparse
import os
import os.path
import re
import shutil
import subprocess
import sys
import tempfile

SCRIPT_PATH = os.path.abspath(os.path.dirname(__file__))
DART_PATH = os.path.abspath(os.path.join(SCRIPT_PATH, '..', '..', '..'))

# Dartium DEPS file with Chrome and WebKit revisions.
DEPS = ('http://dart.googlecode.com/svn/branches/'
        'bleeding_edge/deps/dartium.deps/DEPS')

# Whitelist of files to keep.
WHITELIST = [
    r'LICENSE(\S+)',
    r'(\S+)\.idl',
    r'(\S+)\.json',
    r'(\S+)\.py',
    ]

# WebKit / WebCore info.
WEBKIT_URL_PATTERN = r'"dartium_webkit_trunk": "(\S+)",'
WEBKIT_REV_PATTERN = r'"dartium_webkit_revision": "(\d+)",'
WEBCORE_SUBPATH = 'Source/core'
MODULES_SUBPATH = 'Source/modules'
LOCAL_WEBKIT_IDL_PATH = os.path.join(DART_PATH, 'third_party', 'WebCore')
LOCAL_WEBKIT_README = """\
This directory contains a copy of WebKit/WebCore IDL files.
See the attached LICENSE-* files in this directory.

Please do not modify the files here.  They are periodically copied
using the script: $DART_ROOT/sdk/lib/html/scripts/%(script)s

The current version corresponds to:
URL: %(url)s
Current revision: %(revision)s
"""

# Chrome info.
CHROME_URL_PATTERN = r'"chromium_url": "(\S+)",'
CHROME_REV_PATTERN = r'"chromium_revision": "(\d+)",'
CHROME_IDL_SUBPATH = 'trunk/src/chrome/common/extensions/api'
CHROME_COMMENT_EATER_SUBPATH = 'trunk/src/tools/json_comment_eater'
CHROME_COMPILER_SUBPATH = 'trunk/src/tools/json_schema_compiler'
CHROME_IDL_PARSER_SUBPATH = 'trunk/src/ppapi/generators'
CHROME_PLY_SUBPATH = 'trunk/src/third_party/ply'
LOCAL_CHROME_IDL_PATH = os.path.join(DART_PATH, 'third_party', 'chrome', 'idl')
LOCAL_CHROME_COMMENT_EATER_PATH = os.path.join(
      DART_PATH, 'third_party', 'chrome', 'tools', 'json_comment_eater')
LOCAL_CHROME_COMPILER_PATH = os.path.join(DART_PATH, 'third_party', 'chrome',
                                          'tools', 'json_schema_compiler')
LOCAL_CHROME_IDL_PARSER_PATH = os.path.join(DART_PATH, 'third_party', 'chrome',
                                            'ppapi', 'generators')
LOCAL_CHROME_PLY_PATH = os.path.join(DART_PATH, 'third_party', 'chrome',
                                     'third_party', 'ply')
LOCAL_CHROME_README = """\
This directory contains a copy of Chromium IDL and generation scripts
used to generate Dart APIs for Chrome Apps.

The original files are from:
URL: %(url)s
Current revision: %(revision)s

Please see the corresponding LICENSE file at
%(url)s/trunk/src/LICENSE.
"""
DEPTH_FILES = 'files'
DEPTH_INFINITY = 'infinity'

# Regular expressions corresponding to URL/revision patters in the
# DEPS file.
DEPS_PATTERNS = {
    'webkit': (WEBKIT_URL_PATTERN, WEBKIT_REV_PATTERN),
    'chrome': (CHROME_URL_PATTERN, CHROME_REV_PATTERN),
    }

# List of components to update.
UPDATE_LIST = [
    # (component, remote subpath, local path, local readme file, depth)

    # WebKit IDL.
    ('webkit', WEBCORE_SUBPATH, os.path.join(LOCAL_WEBKIT_IDL_PATH, 'core'), LOCAL_WEBKIT_README,

     DEPTH_INFINITY),
    ('webkit', MODULES_SUBPATH, os.path.join(LOCAL_WEBKIT_IDL_PATH, 'modules'), LOCAL_WEBKIT_README,
     DEPTH_INFINITY),
    # Chrome IDL.
    ('chrome', CHROME_IDL_SUBPATH, LOCAL_CHROME_IDL_PATH, LOCAL_CHROME_README,
     DEPTH_INFINITY),
    # Chrome PPAPI generators. Contains idl_parser.py which is used by the
    # Chrome IDL compiler.
    ('chrome', CHROME_IDL_PARSER_SUBPATH, LOCAL_CHROME_IDL_PARSER_PATH,
     LOCAL_CHROME_README, DEPTH_FILES),
    # ply files.
    ('chrome', CHROME_PLY_SUBPATH, LOCAL_CHROME_PLY_PATH, LOCAL_CHROME_README,
     DEPTH_INFINITY),
    # Path for json_comment_eater, which is needed by the Chrome IDL compiler.
    ('chrome', CHROME_COMMENT_EATER_SUBPATH, LOCAL_CHROME_COMMENT_EATER_PATH,
     LOCAL_CHROME_README, DEPTH_FILES),
    # Chrome IDL compiler files.
    ('chrome', CHROME_COMPILER_SUBPATH, LOCAL_CHROME_COMPILER_PATH,
     LOCAL_CHROME_README, DEPTH_INFINITY),
    ]


def RunCommand(cmd, valid_exits=[0]):
  """Executes a shell command and return its stdout."""
  print ' '.join(cmd)
  pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  output = pipe.communicate()
  if pipe.returncode in valid_exits:
    return output[0]
  else:
    print output[1]
    print 'FAILED. RET_CODE=%d' % pipe.returncode
    sys.exit(pipe.returncode)


def GetDeps():
  """Returns the DEPS file contents with pinned revision info."""
  return RunCommand(['svn', 'cat', DEPS])


def GetSvnRevision(deps, component):
  """Returns a tuple with the (dartium webkit repo, latest revision)."""
  url_pattern, rev_pattern = DEPS_PATTERNS[component]
  url = re.search(url_pattern, deps).group(1)
  revision = re.search(rev_pattern, deps).group(1)
  return (url, revision)


def RefreshFiles(url, revision, remote_path, local_path, depth):
  """Refreshes refreshes files in the local_path to specific url /
  revision / remote_path, exporting to depth"""
  cwd = os.getcwd()
  try:
    if os.path.exists(local_path):
      shutil.rmtree(local_path)
    head, tail = os.path.split(local_path)
    if not os.path.exists(head):
      os.makedirs(head)
    os.chdir(head)
    RunCommand(['svn', 'export', '--depth', depth, '-r', revision,
                url + '/' + remote_path, tail])
  finally:
    os.chdir(cwd)


def PruneExtraFiles(local_path):
  """Removes all files that do not match the whitelist."""
  pattern = re.compile(reduce(lambda x,y: '%s|%s' % (x,y),
                              map(lambda z: '(%s)' % z, WHITELIST)))
  for (root, dirs, files) in os.walk(local_path, topdown=False):
    for f in files:
      if not pattern.match(f):
        os.remove(os.path.join(root, f))
    for d in dirs:
      dirpath = os.path.join(root, d)
      if not os.listdir(dirpath):
        shutil.rmtree(dirpath)


def GenerateReadme(local_path, template, url, revision):
  readme = template % {
    'script': os.path.basename(__file__),
    'url': url,
    'revision': revision }

  readme_path = os.path.join(local_path, 'README')
  out = open(readme_path, 'w')
  out.write(readme)
  out.close()

ZIP_ARCHIVE = 'version-control-dirs.zip'

def SaveVersionControlDir(local_path):
  if os.path.exists(local_path):
    RunCommand([
      'sh', '-c',
      'find %s -name .svn -or -name .git | zip -r %s -@' % (
          os.path.relpath(local_path), ZIP_ARCHIVE)
    ], [0, 12])  # It is ok if zip has nothing to do (exit code 12).

def RestoreVersionControlDir(local_path):
  archive_path = os.path.join(local_path, ZIP_ARCHIVE)
  if os.path.exists(archive_path):
    RunCommand(['unzip', ZIP_ARCHIVE, '-d', '.'])
    RunCommand(['rm', ZIP_ARCHIVE])

def ParseOptions():
  parser = optparse.OptionParser()
  parser.add_option('--webkit-revision', '-w', dest='webkit_revision',
                    help='WebKit IDL revision to install', default=None)
  parser.add_option('--chrome-revision', '-c', dest='chrome_revision',
                    help='Chrome IDL revision to install', default=None)
  parser.add_option('--update', '-u', dest='update',
                    help='IDL to update (webkit | chrome | all)',
                    default='webkit')
  args, _ = parser.parse_args()
  update = {}
  if args.update == 'all' or args.update == 'chrome':
    update['chrome'] = args.chrome_revision
  if args.update == 'all' or args.update == 'webkit':
    update['webkit'] = args.webkit_revision
  return update


def main():
  deps = GetDeps()
  update = ParseOptions()
  for (component, remote_path, local_path, readme, depth) in UPDATE_LIST:
    if component in update.keys():
      revision = update[component]
      url, latest = GetSvnRevision(deps, component)
      if revision is None:
        revision = latest
      SaveVersionControlDir(local_path);
      RefreshFiles(url, revision, remote_path, local_path, depth)
      PruneExtraFiles(local_path)
      GenerateReadme(local_path, readme, url, revision)
      RestoreVersionControlDir(local_path);

if __name__ == '__main__':
  main()
