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

"""Runs Closure compiler on JavaScript files to check for errors and produce
minified output."""

import argparse
import os
import re
import subprocess
import sys
import tempfile

import build.inputs
import processor
import error_filter


_CURRENT_DIR = os.path.join(os.path.dirname(__file__))


class Checker(object):
  """Runs the Closure compiler on given source files to typecheck them
  and produce minified output."""

  _JAR_COMMAND = [
    "java",
    "-jar",
    "-Xms1024m",
    "-client",
    "-XX:+TieredCompilation"
  ]

  _MAP_FILE_FORMAT = "%s.map"

  _POLYMER_EXTERNS = os.path.join(_CURRENT_DIR, "externs", "polymer-1.0.js")

  def __init__(self, verbose=False):
    """
    Args:
      verbose: Whether this class should output diagnostic messages.
      strict: Whether the Closure Compiler should be invoked more strictly.
    """
    self._runner_jar = os.path.join(_CURRENT_DIR, "runner", "runner.jar")
    self._target = None
    self._temp_files = []
    self._verbose = verbose
    self._error_filter = error_filter.PromiseErrorFilter()

  def _nuke_temp_files(self):
    """Deletes any temp files this class knows about."""
    if not self._temp_files:
      return

    self._log_debug("Deleting temp files: %s" % ", ".join(self._temp_files))
    for f in self._temp_files:
      os.remove(f)
    self._temp_files = []

  def _log_debug(self, msg, error=False):
    """Logs |msg| to stdout if --verbose/-v is passed when invoking this script.

    Args:
      msg: A debug message to log.
    """
    if self._verbose:
      print "(INFO) %s" % msg

  def _log_error(self, msg):
    """Logs |msg| to stderr regardless of --flags.

    Args:
      msg: An error message to log.
    """
    print >> sys.stderr, "(ERROR) %s" % msg

  def _run_jar(self, jar, args):
    """Runs a .jar from the command line with arguments.

    Args:
      jar: A file path to a .jar file
      args: A list of command line arguments to be passed when running the .jar.

    Return:
      (exit_code, stderr) The exit code of the command (e.g. 0 for success) and
          the stderr collected while running |jar| (as a string).
    """
    shell_command = " ".join(self._JAR_COMMAND + [jar] + args)
    self._log_debug("Running jar: %s" % shell_command)

    devnull = open(os.devnull, "w")
    kwargs = {"stdout": devnull, "stderr": subprocess.PIPE, "shell": True}
    process = subprocess.Popen(shell_command, **kwargs)
    _, stderr = process.communicate()
    return process.returncode, stderr

  def _get_line_number(self, match):
    """When chrome is built, it preprocesses its JavaScript from:

      <include src="blah.js">
      alert(1);

    to:

      /* contents of blah.js inlined */
      alert(1);

    Because Closure Compiler requires this inlining already be done (as
    <include> isn't valid JavaScript), this script creates temporary files to
    expand all the <include>s.

    When type errors are hit in temporary files, a developer doesn't know the
    original source location to fix. This method maps from /tmp/file:300 back to
    /original/source/file:100 so fixing errors is faster for developers.

    Args:
      match: A re.MatchObject from matching against a line number regex.

    Returns:
      The fixed up /file and :line number.
    """
    real_file = self._processor.get_file_from_line(match.group(1))
    return "%s:%d" % (os.path.abspath(real_file.file), real_file.line_number)

  def _filter_errors(self, errors):
    """Removes some extraneous errors. For example, we ignore:

      Variable x first declared in /tmp/expanded/file

    Because it's just a duplicated error (it'll only ever show up 2+ times).
    We also ignore Promise-based errors:

      found   : function (VolumeInfo): (Promise<(DirectoryEntry|null)>|null)
      required: (function (Promise<VolumeInfo>): ?|null|undefined)

    as templates don't work with Promises in all cases yet. See
    https://github.com/google/closure-compiler/issues/715 for details.

    Args:
      errors: A list of string errors extracted from Closure Compiler output.

    Return:
      A slimmer, sleeker list of relevant errors (strings).
    """
    first_declared_in = lambda e: " first declared in " not in e
    return self._error_filter.filter(filter(first_declared_in, errors))

  def _clean_up_error(self, error):
    """Reverse the effects that funky <include> preprocessing steps have on
    errors messages.

    Args:
      error: A Closure compiler error (2 line string with error and source).

    Return:
      The fixed up error string.
    """
    assert self._target
    assert self._expanded_file
    expanded_file = self._expanded_file
    fixed = re.sub("%s:(\d+)" % expanded_file, self._get_line_number, error)
    return fixed.replace(expanded_file, os.path.abspath(self._target))

  def _format_errors(self, errors):
    """Formats Closure compiler errors to easily spot compiler output.

    Args:
      errors: A list of strings extracted from the Closure compiler's output.

    Returns:
      A formatted output string.
    """
    contents = "\n## ".join("\n\n".join(errors).splitlines())
    return "## %s" % contents if contents else ""

  def _create_temp_file(self, contents):
    """Creates an owned temporary file with |contents|.

    Args:
      content: A string of the file contens to write to a temporary file.

    Return:
      The filepath of the newly created, written, and closed temporary file.
    """
    with tempfile.NamedTemporaryFile(mode="wt", delete=False) as tmp_file:
      self._temp_files.append(tmp_file.name)
      tmp_file.write(contents)
    return tmp_file.name

  def check(self, sources, out_file=None, runner_args=None, closure_args=None,
            custom_sources=True):
    """Closure compile |sources| while checking for errors.

    Args:
      sources: Files to check. sources[0] is the typically the target file.
          sources[1:] are externs and dependencies in topological order. Order
          is not guaranteed if custom_sources is True.
      out_file: A file where the compiled output is written to.
      runner_args: Arguments passed to runner.jar.
      closure_args: Arguments passed directly to the Closure compiler.
      custom_sources: Whether |sources| was customized by the target (e.g. not
          in GYP dependency order).

    Returns:
      (found_errors, stderr) A boolean indicating whether errors were found and
          the raw Closure compiler stderr (as a string).
    """
    is_extern = lambda f: 'extern' in f
    externs_and_deps = [self._POLYMER_EXTERNS]

    if custom_sources:
      externs_and_deps += sources
    else:
      self._target = sources[0]
      externs_and_deps += sources[1:]

    externs = filter(is_extern, externs_and_deps)
    deps = filter(lambda f: not is_extern(f), externs_and_deps)

    assert externs or deps or self._target

    self._log_debug("Externs: %s" % externs)
    self._log_debug("Dependencies: %s" % deps)
    self._log_debug("Target: %s" % self._target)

    js_args = deps + ([self._target] if self._target else [])

    if not custom_sources:
      # TODO(dbeam): compiler.jar automatically detects "@externs" in a --js arg
      # and moves these files to a different AST tree. However, because we use
      # one big funky <include> meta-file, it thinks all the code is one big
      # externs. Just use --js when <include> dies.

      cwd, tmp_dir = os.getcwd(), tempfile.gettempdir()
      rel_path = lambda f: os.path.join(os.path.relpath(cwd, tmp_dir), f)
      contents = ['<include src="%s">' % rel_path(f) for f in js_args]
      meta_file = self._create_temp_file("\n".join(contents))
      self._log_debug("Meta file: %s" % meta_file)

      self._processor = processor.Processor(meta_file)
      self._expanded_file = self._create_temp_file(self._processor.contents)
      self._log_debug("Expanded file: %s" % self._expanded_file)

      js_args = [self._expanded_file]

    closure_args = closure_args or []
    closure_args += ["summary_detail_level=3"]

    args = ["--externs=%s" % e for e in externs] + \
           ["--js=%s" % s for s in js_args] + \
           ["--%s" % arg for arg in closure_args]

    if out_file:
      out_dir = os.path.dirname(out_file)
      if not os.path.exists(out_dir):
        os.makedirs(out_dir)
      args += ["--js_output_file=%s" % out_file]
      args += ["--create_source_map=%s" % (self._MAP_FILE_FORMAT % out_file)]

    args_file_content = " %s" % " ".join(args)
    self._log_debug("Args: %s" % args_file_content.strip())

    args_file = self._create_temp_file(args_file_content)
    self._log_debug("Args file: %s" % args_file)

    processed_runner_args = ["--%s" % arg for arg in runner_args or []]
    processed_runner_args += ["--compiler-args-file=%s" % args_file]
    _, stderr = self._run_jar(self._runner_jar, processed_runner_args)

    errors = stderr.strip().split("\n\n")
    maybe_summary = errors.pop()

    summary = re.search("(?P<error_count>\d+).*error.*warning", maybe_summary)
    if summary:
      self._log_debug("Summary: %s" % maybe_summary)
    else:
      # Not a summary. Running the jar failed. Bail.
      self._log_error(stderr)
      self._nuke_temp_files()
      sys.exit(1)

    if summary.group('error_count') != "0" and out_file:
      if os.path.exists(out_file):
        os.remove(out_file)
      if os.path.exists(self._MAP_FILE_FORMAT % out_file):
        os.remove(self._MAP_FILE_FORMAT % out_file)

    if not custom_sources:
      filtered_errors = self._filter_errors(errors)
      errors = map(self._clean_up_error, filtered_errors)
      output = self._format_errors(errors)

      if errors:
        prefix = "\n" if output else ""
        self._log_error("Error in: %s%s%s" % (self._target, prefix, output))
      elif output:
        self._log_debug("Output: %s" % output)

    self._nuke_temp_files()
    return bool(errors), stderr


if __name__ == "__main__":
  parser = argparse.ArgumentParser(
      description="Typecheck JavaScript using Closure compiler")
  parser.add_argument("sources", nargs=argparse.ONE_OR_MORE,
                      help="Path to a source file to typecheck")
  parser.add_argument("--custom_sources", action="store_true",
                      help="Whether this rules has custom sources.")
  parser.add_argument("-o", "--out_file",
                      help="A file where the compiled output is written to")
  parser.add_argument("-r", "--runner_args", nargs=argparse.ZERO_OR_MORE,
                      help="Arguments passed to runner.jar")
  parser.add_argument("-c", "--closure_args", nargs=argparse.ZERO_OR_MORE,
                      help="Arguments passed directly to the Closure compiler")
  parser.add_argument("-v", "--verbose", action="store_true",
                      help="Show more information as this script runs")
  opts = parser.parse_args()

  checker = Checker(verbose=opts.verbose)

  found_errors, stderr = checker.check(opts.sources, out_file=opts.out_file,
                                       closure_args=opts.closure_args,
                                       runner_args=opts.runner_args,
                                       custom_sources=opts.custom_sources)

  if found_errors:
    if opts.custom_sources:
      print stderr
    sys.exit(1)
