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

"""
Legpad is used to compile .dart files to javascript, using the dart2js compiler.

This is accomplished by creating an html file (usually called
<something>.legpad.html) that executes the dart2js compiler when the page
is loaded by a web browser (or DumpRenderTree).

The <something>.legpad.html file contains:

  1. all the dart files that compose a user's dart program
  2. all the dart files of dart:core and other standard dart libraries
      (or any other symbol that can follow "dart:" in an import statement
  3. legpad.dart (compiled to javascript)

The contents of each dart file is placed in a separate <script> tag.

When the html page is loaded by a browser, the leg compiler is invoked
and the dart program is compiled to javascript.  The generated javascript is
placed in a <pre> element with id "output".

When the html page is passed to DumpRenderTree, the dumped output will
have the generated javascript.

See 'example.sh' for an example of how to run legpad.
"""

import logging
import optparse
import os.path
import platform
import re
import subprocess
import sys


class FileNotFoundException(Exception):
  def __init__(self, file_name):
    self._name = file_name

  def __str__(self):
    return self._name


class CommandFailedException(Exception):
  def __init__(self, message):
    self._message = message

  def GetMessage(self):
    return self._message


# Template for the legpad.html page we're going to generate.
HTML = """<!DOCTYPE html>
<html>
<head>
  <style type="text/css">
    textarea {
      width: 100%;
      height: 200px;
    }
    .label {
      margin-top: 5px;
    }
    pre {
      border: 2px solid black;
    }
  </style>
  {{script_tags}}
  <script type="text/javascript">
    if (window.layoutTestController) {
      layoutTestController.dumpAsText();
    }
  </script>
</head>
<body>
  <h1>Legpad</h1>
  <div class="label">Input:</div>
  <textarea id="input"></textarea>
  <div class="label">Compiler Messages:</div>
  <pre id="warnings"></pre>
  <div class="label">Timing:</div>
  <pre id="timing"></pre>
  <div class="label">Output:</div>
  <pre id="output"></pre>
  <script type="text/javascript">
    {{LEGPAD_JS}}
  </script>
</body>
</html>
"""

# This finds everything after the word "Output:" in the html page.
# (Note, because the javascript we're fishing out spans multiple lines
# we need to use the DOTALL switch here.)
OUTPUT_JAVASCRIPT_REGEX = re.compile(".*\nOutput:\n(.*)\n#EOF", re.DOTALL)

# If the legpad.dart encounters a compilation error, the generated
# javascript will contains the words "dart2js compilation error".
COMPILATION_ERROR_REGEX = re.compile(".*dart2js compilation error.*", re.DOTALL)

# We use "application/inert" here to make the browser ignore the
# these script tags.  (legpad.dart will fish out the contents as needed.)
#
SCRIPT_TAG = """<script type="application/inert" id="{{id}}">
{{contents}}
</script>
"""

# Regex that finds #import, #source and #native directives in .dart files.
#   match.group(1) = "import", "source" or "native"
#   match.group(2) = url of file being imported
DIRECTIVE_RE = re.compile(r"^#(import|source|native)\([\"']([^\"']*)[\"']")

# id of script tag that holds name of the top dart file to be compiled,
# (This file name passed will be passed to the leg compiler by legpad.dart.)
MAIN_ID = "main_id"

# TODO(mattsh): read this from some config file once ahe/zundel create it
DART_LIBRARIES = {
    "core": "lib/compiler/implementation/lib/core.dart",
    "_js_helper": "lib/compiler/implementation/lib/js_helper.dart",
    "_interceptors": "lib/compiler/implementation/lib/interceptors.dart",
    "dom": "lib/dom/frog/dom_frog.dart",
    "html": "lib/html/frog/html_frog.dart",
    "io": "lib/compiler/implementation/lib/io.dart",
    "isolate": "lib/isolate/isolate_leg.dart",
    "json": "lib/json/json.dart",
    "uri": "lib/uri/uri.dart",
    "utf": "lib/utf/utf.dart",
}

class Pad(object):
  """
  Accumulates all source files that are needed to compile a dart program,
  and places them in <script> tags on an html page.
  """

  def __init__(self, argv):
    parser = optparse.OptionParser(usage=
      "%prog [options] file_to_compile.dart"
    )
    parser.add_option("-o", "--out",
        help="name of javascript output file")
    parser.add_option("-v", "--verbose", action="store_true",
        help="more verbose logging")
    (options, args) = parser.parse_args(argv)

    log_level = logging.INFO
    if options.verbose:
      log_level = logging.DEBUG
    logging.basicConfig(level=log_level)

    if len(args) < 2:
      parser.print_help()
      sys.exit(1)

    self.main_file = os.path.abspath(args[1])

    # directory of this script
    self.legpad_dir = os.path.abspath(os.path.dirname(argv[0]))

    # root of dart source repo
    self.dart_dir = os.path.dirname(os.path.dirname(os.path.dirname(
        self.legpad_dir)))

    logging.debug("dart_dir: '%s'" % self.dart_dir)

    if options.out:
      # user has specified an output file name
      self.js_file = os.path.abspath(options.out)
    else:
      # User didn't specify an output file, so use the input
      # file name as the base of the output file name.
      self.js_file = self.main_file + ".legpad.js"

    logging.debug("js_file: '%s" % self.js_file)

    # this is the html file that we pass to DumpRenderTree
    self.html_file = self.main_file + ".legpad.html"
    logging.debug("html_file: '%s'" % self.html_file)

    # map from file name to File object (contains entries for all corelib
    # and all other dart files needed to compile main_file)
    self.name_to_file = {}

    # map from script tag id to File object
    self.id_to_file = {}

    self.load_libraries()
    self.load_file(self.main_file)

    html = self.generate_html()
    write_file(self.html_file, html)

    js = self.generate_js()
    write_file(self.js_file, js)

    line_count = len(js.splitlines())
    logging.debug("generated '%s' (%d lines)", self.js_file, line_count)

    match = COMPILATION_ERROR_REGEX.match(js)
    if match:
      sys.exit(1)

  def generate_html(self):
    tags = []
    for f in self.id_to_file.values():
      tags.append(self._create_tag(f.id, f.contents))
    tags.append(self._create_tag(MAIN_ID, self.shorten(self.main_file)))
    html = HTML.replace("{{script_tags}}", "".join(tags))

    legpad_js = os.path.join(self.legpad_dir, "legpad.dart.js")
    check_exists(legpad_js)

    html = html.replace("{{LEGPAD_JS}}", read_file(legpad_js))
    return html

  def generate_js(self):
    drt = os.path.join(self.dart_dir, "client/tests/drt/DumpRenderTree")
    if platform.system() == 'Darwin':
      drt += ".app"
    elif platform.system() == 'Windows':
      raise Exception("legpad does not run on Windows")

    check_exists(drt)
    args = []
    args.append(drt)
    args.append(self.html_file)

    stdout = run_command(args)
    match = OUTPUT_JAVASCRIPT_REGEX.match(stdout)
    if not match:
      raise Exception("can't find regex in DumpRenderTree output")
    return match.group(1)

  @staticmethod
  def _create_tag(id, contents):
    s = SCRIPT_TAG
    s = s.replace("{{id}}", id)
    # TODO(mattsh) - need to html escape here
    s = s.replace("{{contents}}", contents)
    return s

  def dart_library(self, name):
    path = DART_LIBRARIES[name]
    if not path:
      raise Exception("unrecognized 'dart:%s'", name)
    return os.path.join(self.dart_dir, path)

  def load_libraries(self):
    for name in DART_LIBRARIES:
      self.load_file(self.dart_library(name))

  def load_file(self, name):
    name = os.path.abspath(name)
    if name in self.name_to_file:
      return
    f = File(self, name)
    self.name_to_file[f.name] = f
    if f.id in self.id_to_file:
      raise Exception("ambiguous id '%s'" % f.id)
    self.id_to_file[f.id] = f
    f.directives()

  def shorten(self, name):
    """
    Change that full path of the dart svn repo to simply "dartdir"
    """
    return name.replace(self.dart_dir, "dartdir")

  def make_id(self, name):
    """
    Generates an id (based on the file name) for the <script> tag that will
    hold the contents of this file.
    """
    return self.shorten(name).replace("/", "_").replace(".", "_")


class File(object):
  def __init__(self, pad, name):
    self.pad = pad
    self.name = name
    self.id = pad.make_id(name)
    self.contents = read_file(name)

  def directives(self):
    """Load files referenced by #source, #import and #native directives."""
    lines = self.contents.split("\n")
    self.line_number = 0
    for line in lines:
      self.line_number += 1
      self._directive(line)

  def _directive(self, line):
    match = DIRECTIVE_RE.match(line)
    if not match:
      return
    url = match.group(2)
    if url.startswith("dart:"):
      path = self.pad.dart_library(url[len("dart:"):])
    else:
      path = os.path.join(os.path.dirname(self.name), url)
    self.pad.load_file(path)


def read_file(file_name):
  check_exists(file_name)
  with open(file_name, "r") as input:
    contents = input.read()
  logging.debug("read_file '%s' (%d bytes)" % (file_name, len(contents)))
  return contents


def write_file(file_name, contents):
  with open(file_name, "w") as output:
    output.write(contents)

  check_exists(file_name)
  logging.debug("write_file '%s' (%d bytes)" % (file_name, len(contents)))


def check_exists(file_name):
  if not os.path.exists(file_name):
    raise FileNotFoundException(file_name)


def format_command(args):
  return ' '.join(args)


def run_command(args):
  """
  Args:
    command: comamnd with arguments to exec
  Returns:
    all output that this command sent to stdout
  """

  command = format_command(args)
  logging.info("RUNNING: '%s'" % command)
  child = subprocess.Popen(args,
      stdout=subprocess.PIPE,
      stderr=subprocess.PIPE,
      close_fds=True)
  (stdout, stderr) = child.communicate()
  exit_code = child.wait()
  if exit_code:
    for line in stderr.splitlines():
      logging.info(line)
    msg = "FAILURE (exit_code=%d): '%s'" % (exit_code, command)
    logging.error(msg)
    raise CommandFailedException(msg)
  logging.debug("SUCCEEDED (%d bytes)" % len(stdout))
  return stdout


def main(argv):
  Pad(argv)

if __name__ == "__main__":
  sys.exit(main(sys.argv))
