#!/usr/bin/env python
# Copyright (c) 2011, 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.
"""Used to merge and copy dart source files for deployment to AppEngine"""

import fileinput
import sys
import shutil
import os
import re
from os.path import abspath, basename, dirname, exists, isabs, join
from glob import glob

re_directive = re.compile(
    r'^(library|import|part|native|resource)\s+(.*);$')
re_comment = re.compile(
    r'^(///|/\*| \*).*$')

class Library(object):
  def __init__(self, name, imports, sources, natives, code, comment):
    self.name = name
    self.imports = imports
    self.sources = sources
    self.natives = natives
    self.code = code
    self.comment = comment

def parseLibrary(library):
  """ Parses a .dart source file that is the root of a library, and returns
      information about it: the name, the imports, included sources, and any
      code in the file.
  """
  libraryname = None
  imports = []
  sources = []
  natives = []
  inlinecode = []
  librarycomment = []
  if exists(library):
    # TODO(sigmund): stop parsing when import/source
    for line in fileinput.input(library):
      match = re_directive.match(line)
      if match:
        directive = match.group(1)
        if directive == 'library':
          assert libraryname is None
          libraryname = match.group(2)
        elif directive == 'part':
          suffix = match.group(2)
          if not suffix.startswith('of '):
            sources.append(match.group(2).strip('"\''))
        elif directive == 'import':
          imports.append(match.group(2))
        else:
          raise Exception('unknown directive %s in %s' % (directive, line))
      else:
        # Check for library comment.
        if not libraryname and re_comment.match(line):
          librarycomment.append(line)
        else:
          inlinecode.append(line)
    fileinput.close()
  return Library(libraryname, imports, sources, natives, inlinecode,
                 librarycomment)

def normjoin(*args):
  return os.path.normpath(os.path.join(*args))

def mergefiles(srcs, dstfile):
  for src in srcs:
    with open(src, 'r') as s:
      for line in s:
        if not line.startswith('part of '):
          dstfile.write(line)

def main(outdir = None, *inputs):
  if not outdir or not inputs:
    print "Usage: %s OUTDIR INPUTS" % args[0]
    print "  OUTDIR is the war directory to copy to"
    print "  INPUTS is a list of files or patterns used to specify the input"
    print "   .dart files"
    print "This script should be run from the client root directory."
    print "Files will be merged and copied to: OUTDIR/relative-path-of-file,"
    print "except for dart files with absolute paths, which will be copied to"
    print " OUTDIR/absolute-path-as-directories"
    return 1

  entry_libraries = []
  for i in inputs:
    entry_libraries.extend(glob(i))

  for entrypoint in entry_libraries:
    # Get the transitive set of dart files this entrypoint depends on, merging
    # each library along the way.
    worklist = [os.path.normpath(entrypoint)]
    seen = set()
    while len(worklist) > 0:
      lib = worklist.pop()
      if lib in seen:
        continue

      seen.add(lib)

      if (dirname(dirname(lib)).endswith('dom/generated/src')
          or dirname(lib).endswith('dom/src')):
        continue

      library = parseLibrary(lib)

      # Ensure output directory exists
      outpath = join(outdir, lib[1:] if isabs(lib) else lib)
      dstpath = dirname(outpath)
      if not exists(dstpath):
        os.makedirs(dstpath)


      # Create file containing all imports, and inlining all sources
      with open(outpath, 'w') as f:
        if library.name:
          if library.comment:
            f.write('%s' % (''.join(library.comment)))
          f.write("library %s;\n\n" % library.name)
        else:
          f.write("library %s;\n\n" % basename(lib))
        for importfile in library.imports:
          f.write("import %s;\n" % (importfile))
        f.write('%s' % (''.join(library.code)))
        mergefiles([normjoin(dirname(lib), s) for s in library.sources], f)

      for suffix in library.imports:
        m = re.match(r'[\'"]([^\'"]+)[\'"](\s+as\s+\w+)?.*$', suffix)
        uri = m.group(1)
        if not uri.startswith('dart:'):
          worklist.append(normjoin(dirname(lib), uri));

  return 0

if __name__ == '__main__':
  sys.exit(main(*sys.argv[1:]))
