#!/usr/bin/python2.7
# 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 os
import re
from os.path import 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" % sys.argv[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:
                prefix = os.environ.get('DART_HTML_PREFIX')
                if prefix:
                    f.write(prefix + '\n')
                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:]))
