#!/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

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/WebCore'
LOCAL_WEBKIT_IDL_PATH = os.path.join(DART_PATH, 'third_party', 'WebCore')
LOCAL_WEBKIT_README = os.path.join(LOCAL_WEBKIT_IDL_PATH, 'README')
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_TOOLS_SUBPATH = 'trunk/src/tools/json_schema_compiler'
LOCAL_CHROME_IDL_PATH = os.path.join(DART_PATH, 'third_party', 'chrome', 'idl')
LOCAL_CHROME_TOOLS_PATH = os.path.join(DART_PATH, 'third_party', 'chrome',
                                       'tools')
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.
"""

# 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)

    # WebKit IDL.
    ('webkit', WEBCORE_SUBPATH, LOCAL_WEBKIT_IDL_PATH, LOCAL_WEBKIT_README),
    # Chrome IDL.
    ('chrome', CHROME_IDL_SUBPATH, LOCAL_CHROME_IDL_PATH, LOCAL_CHROME_README),
    # Chrome IDL compiler files.
    ('chrome', CHROME_TOOLS_SUBPATH, LOCAL_CHROME_TOOLS_PATH,
     LOCAL_CHROME_README),
    ]


def RunCommand(cmd):
  """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 == 0:
    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 RefreshIDL(url, revision, remote_path, local_path):
  """Refreshes refreshes files in the local_path to specific url /
  revision / remote_path."""
  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', '-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()


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) in UPDATE_LIST:
    if component in update.keys():
      revision = update[component]
      url, latest = GetSvnRevision(deps, component)
      if revision is None:
        revision = latest
      RefreshIDL(url, revision, remote_path, local_path)
      PruneExtraFiles(local_path)
      GenerateReadme(local_path, readme, url, revision)


if __name__ == '__main__':
  main()
