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

from __future__ import with_statement
import StringIO
import os
import sys
import re
from collections import deque

class GenerateError(Exception):

  def __init__(self, value):
    self.value = value

  def __str__(self):
    return repr(self.value)


class Generator:

  def __init__(self, base_directory, name, output, path, *includes):
    self.base_directory = base_directory
    self.name = name
    self.output = output
    self.path = path
    self.includes = set()
    for x in includes:
      self.includes.add(x)
    self.sources = []
    self.resources = []

  def _list_files(self):
    drain = deque()
    drain.extend(self.includes)
    while len(drain) > 0:
      target = drain.popleft()
      # Avoid circular dependencies
      if target in self.resources:
        continue
      if (target.startswith("dart:")):
        continue
      self.resources.append(target)
      if (target.endswith(".dart")):
        with open(os.path.join(self.base_directory,self.path,target),"r") as fobj:
          text = fobj.read()
        file_sources = re.findall(r"#source\(['\"](?P<name>.*)['\"]\);",text)
        file_native = re.findall(r"#native\(['\"](?P<name>.*)['\"]\);",text)
        file_imports = re.findall(r"#import\(['\"](?P<name>.*)['\"]\);",text)
        self.resources.extend(file_sources)
        self.resources.extend(file_native)
        drain.extend(file_imports)
    self.sources.sort()
    self.resources.sort()

  def _print_gypi_files(self, out, name, files):
    out.write("    '%s': [\n" % name)
    for filename in files:
      out.write("      '%s/%s',\n" % (self.path, filename))
    out.write("    ],\n")

  def _print_ant_files(self, out, name, files):
    out.write("  <filelist id='%s' dir='%s'>\n" % (name, self.path))
    for filename in files:
      out.write("    <file name='%s'/>\n" % filename)
    out.write("  </filelist>\n")
    out.write("  <pathconvert pathsep=',' property='%s' refid='%s'>\n"
              % (name, name))
    out.write("    <map from='${basedir}/%s/' to=''/>\n" % self.path)
    out.write("  </pathconvert>\n")

  def _make_output(self, file_name):
    if os.path.exists(file_name):
      return StringIO.StringIO()
    else:
      return file(file_name, 'w')

  def _close(self, file_name, output):
    if not isinstance(output, StringIO.StringIO):
      output.close()
      return
    new_text = output.getvalue()
    output.close()
    with open(file_name, 'r') as f:
      old_text = f.read()
    if old_text == new_text:
      return
    sys.stderr.write('Updating %s\n' % file_name)
    with open(file_name, 'w') as f:
      f.write(new_text)

  def generate(self):
    self._list_files()
    file_name = self.output + '.gypi';
    gypi = self._make_output(file_name)
    gypi.write("{\n  'variables': {\n")
    self._print_gypi_files(gypi, self.name + '_sources', self.sources)
    self._print_gypi_files(gypi, self.name + '_resources', self.resources)
    gypi.write("  },\n}\n")
    self._close(file_name, gypi)
    file_name = self.output + '.xml'
    ant = self._make_output(file_name)
    ant.write("<project>\n")
    self._print_ant_files(ant, self.name + '_sources', self.sources)
    self._print_ant_files(ant, self.name + '_resources', self.resources)
    ant.write("</project>\n")
    self._close(file_name, ant)


def Main(script_name = None, name = None, output = None, path = None,
         *rest):
  if not path:
    raise GenerateError("usage: %s NAME OUTPUT PATH EXCLUDE_DIR_NAME ..."
                        % script_name)
  base_directory = os.path.dirname(output)
  Generator(base_directory, name, output, path, *rest).generate()


if __name__ == '__main__':
  sys.exit(Main(*sys.argv))
