#!/usr/bin/python
# Copyright 2014 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.

"""Closure builder for Javascript."""

import argparse
import json
import os
import re

_BASE_REGEX_STRING = r'^\s*goog\.%s\(\s*[\'"](.+)[\'"]\s*\)'
require_regex = re.compile(_BASE_REGEX_STRING % 'require')
provide_regex = re.compile(_BASE_REGEX_STRING % 'provide')

base = os.path.join('third_party',
                    'closure_library',
                    'closure',
                    'goog',
                    'base.js')


def process_file(filename):
  """Extracts provided and required namespaces.

  Description:
    Scans Javascript file for provided and required namespaces.

  Args:
    filename: name of the file to process.

  Returns:
    Pair of lists, where the first list contains namespaces provided by the file
    and the second contains a list of requirements.
  """

  provides = []
  requires = []
  with open(filename, 'r') as file_handle:
    for line in file_handle:
      if re.match(require_regex, line):
        requires.append(re.search(require_regex, line).group(1))
      if re.match(provide_regex, line):
        provides.append(re.search(provide_regex, line).group(1))
  return provides, requires


def extract_dependencies(filename, providers, requirements):
  """Extracts provided and required namespaces for a file.

  Description:
    Updates maps for namespace providers and file prerequisites.

  Args:
    filename: Path of the file to process.
    providers: Mapping of namespace to filename that provides the namespace.
    requirements: Mapping of filename to a list of prerequisite namespaces.
  """

  p, r = process_file(filename)

  for name in p:
    providers[name] = filename
  for name in r:
    if filename not in requirements:
      requirements[filename] = []
    requirements[filename].append(name)


def export(target_file, source_filename, providers, requirements, processed):
  """Writes the contents of a file.

  Description:
    Appends the contents of the source file to the target file. In order to
    preserve proper dependencies, each file has its required namespaces
    processed before exporting the source file itself. The set of exported files
    is tracked to guard against multiple exports of the same file. Comments as
    well as 'provide' and 'require' statements are removed during to export to
    reduce file size.

  Args:
    target_file: Handle to target file for export.
    source_filename: Name of the file to export.
    providers: Map of namespace to filename.
    requirements: Map of filename to required namespaces.
    processed: Set of processed files.
  Returns:
  """

  # Filename may have already been processed if it was a requirement of a
  # previous exported file.
  if source_filename in processed:
    return

  # Export requirements before file.
  if source_filename in requirements:
    for namespace in requirements[source_filename]:
      if namespace in providers:
        dependency = providers[namespace]
        if dependency:
          export(target_file, dependency, providers, requirements, processed)

  processed.add(source_filename)

  # Export file
  for name in providers:
    if providers[name] == source_filename:
      target_file.write('// %s%s' % (name, os.linesep))
  source_file = open(source_filename, 'r')
  try:
    comment_block = False
    for line in source_file:
      # Skip require statements.
      if not re.match(require_regex, line):
        formatted = line.rstrip()
        if comment_block:
          # Scan for trailing */ in multi-line comment.
          index = formatted.find('*/')
          if index >= 0:
            formatted = formatted[index + 2:]
            comment_block = False
          else:
            formatted = ''
        # Remove full-line // style comments.
        if formatted.lstrip().startswith('//'):
          formatted = ''
        # Remove /* */ style comments.
        start_comment = formatted.find('/*')
        end_comment = formatted.find('*/')
        while start_comment >= 0:
          if end_comment > start_comment:
            formatted = (formatted[:start_comment]
                         + formatted[end_comment + 2:])
            start_comment = formatted.find('/*')
            end_comment = formatted.find('*/')
          else:
            formatted = formatted[:start_comment]
            comment_block = True
            start_comment = -1
        if formatted.strip():
          target_file.write('%s%s' % (formatted, os.linesep))
  finally:
    source_file.close()
  target_file.write('\n')


def extract_sources(options):
  """Extracts list of sources based on command line options.

  Args:
    options: Parsed command line options.
  Returns:
    List of source files.  If the path option is specified then file paths are
    absolute.  Otherwise, relative paths may be used.
  """

  sources = None
  if options.json_file:
    # Optionally load list of source files from a json file. Useful when the
    # list of files to process is too long for the command line.
    with open(options.json_file, 'r') as json_file:
      data = []
      # Strip leading comments.
      for line in json_file:
        if not line.startswith('#'):
          data.append(line)
      json_object = json.loads(os.linesep.join(data).replace('\'', '\"'))
      path = options.json_sources.split('.')
      sources = json_object
      for key in path:
        sources = sources[key]
      if options.path:
        sources = [os.path.join(options.path, source) for source in sources]
  else:
    sources = options.sources
  return sources


def main():
  """The entrypoint for this script."""
  parser = argparse.ArgumentParser()
  parser.add_argument('--sources', nargs='*')
  parser.add_argument('--target', nargs=1)
  parser.add_argument('--json_file', nargs='?')
  parser.add_argument('--json_sources', nargs='?')
  parser.add_argument('--path', nargs='?')
  options = parser.parse_args()

  sources = extract_sources(options)
  assert sources, 'Missing source files.'

  providers = {}
  requirements = {}
  for filename in sources:
    extract_dependencies(filename, providers, requirements)

  with open(options.target[0], 'w') as target_file:
    target_file.write('var CLOSURE_NO_DEPS=true;%s' % os.linesep)
    processed = set()
    base_path = base
    if options.path:
      base_path = os.path.join(options.path, base_path)
    export(target_file, base_path, providers, requirements, processed)
    for source_filename in sources:
      export(target_file, source_filename, providers, requirements, processed)

if __name__ == '__main__':
  main()
