# Copyright (c) 2014 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.

import os
import re
import sys
import shutil
import tempfile
import unittest

from vinn import d8_runner


@unittest.skipIf(sys.platform.startswith('win'),
                 'd8 not yet supported on Windows.')
class VinnUnittest(unittest.TestCase):

  @classmethod
  def setUpClass(cls):
    cls.test_data_dir = os.path.abspath(
        os.path.join(os.path.dirname(__file__), 'test_data'))

  def GetTestFilePath(self, file_name):
    return os.path.join(self.test_data_dir, file_name)

  def AssertHasNamedFrame(self, func_name, file_and_linum, exception_message):
    m = re.search('at %s.+\(.*%s.*\)' % (func_name, file_and_linum),
                  exception_message)
    if not m:
      sys.stderr.write('\n=============================================\n')
      msg = "Expected to find %s and %s" % (func_name, file_and_linum)
      sys.stderr.write('%s\n' % msg)
      sys.stderr.write('=========== Begin Exception Message =========\n')
      sys.stderr.write(exception_message)
      sys.stderr.write('=========== End Exception Message =========\n\n')
      self.fail(msg)

  def AssertHasFrame(self, file_and_linum, exception_message):
    m = re.search('at .*%s.*' % file_and_linum, exception_message)
    if not m:
      sys.stderr.write('\n=============================================\n')
      msg = "Expected to find %s" % file_and_linum
      sys.stderr.write('%s\n' % msg)
      sys.stderr.write('=========== Begin Exception Message =========\n')
      sys.stderr.write(exception_message)
      sys.stderr.write('=========== End Exception Message =========\n\n')
      self.fail(msg)

  def testExecuteJsStringStdoutPiping(self):
    tmp_dir = tempfile.mkdtemp()
    try:
      temp_file_name = os.path.join(tmp_dir, 'out_file')
      with open(temp_file_name, 'w') as f:
        d8_runner.ExcecuteJsString(
            'print("Hello w0rld");\n', stdout=f)
      with open(temp_file_name, 'r') as f:
        self.assertEquals(f.read(), 'Hello w0rld\n')
    finally:
      shutil.rmtree(tmp_dir)

  def testRunJsStringStdoutPiping(self):
    tmp_dir = tempfile.mkdtemp()
    try:
      temp_file_name = os.path.join(tmp_dir, 'out_file')
      with open(temp_file_name, 'w') as f:
        d8_runner.RunJsString(
            'print("Hello w0rld");\n', stdout=f)
      with open(temp_file_name, 'r') as f:
        self.assertEquals(f.read(), 'Hello w0rld\n')
    finally:
      shutil.rmtree(tmp_dir)

  def testExecuteFileStdoutPiping(self):
    file_path = self.GetTestFilePath('simple.js')
    tmp_dir = tempfile.mkdtemp()
    try:
      temp_file_name = os.path.join(tmp_dir, 'out_file')
      with open(temp_file_name, 'w') as f:
        d8_runner.ExecuteFile(file_path, stdout=f)
      with open(temp_file_name, 'r') as f:
        self.assertEquals(f.read(), 'Hello W0rld from simple.js\n')
    finally:
      shutil.rmtree(tmp_dir)

  def testRunFileStdoutPiping(self):
    file_path = self.GetTestFilePath('simple.js')
    tmp_dir = tempfile.mkdtemp()
    try:
      temp_file_name = os.path.join(tmp_dir, 'out_file')
      with open(temp_file_name, 'w') as f:
        d8_runner.RunFile(file_path, stdout=f)
      with open(temp_file_name, 'r') as f:
        self.assertEquals(f.read(), 'Hello W0rld from simple.js\n')
    finally:
      shutil.rmtree(tmp_dir)

  def testSimpleJsExecution(self):
    file_path = self.GetTestFilePath('print_file_content.js')
    dummy_test_path = self.GetTestFilePath('dummy_test_file')
    output = d8_runner.ExecuteFile(file_path, source_paths=[self.test_data_dir],
                                   js_args=[dummy_test_path])
    self.assertIn(
        'This is file contains only data for testing.\n1 2 3 4', output)

  def testDuplicateSourcePaths(self):
    output = d8_runner.ExcecuteJsString(
      "loadHTML('/load_simple_html.html');",
      source_paths=[self.test_data_dir]*100)
    self.assertIn(
        'load_simple_html.html is loaded', output)

  def testJsFileLoadHtmlFile(self):
    file_path = self.GetTestFilePath('load_simple_html.js')
    output = d8_runner.ExecuteFile(file_path, source_paths=[self.test_data_dir])
    expected_output = ('File foo.html is loaded\n'
                       'x = 1\n'
                       "File foo.html's second script is loaded\n"
                       'x = 2\n'
                       'load_simple_html.js is loaded\n')
    self.assertEquals(output, expected_output)

  def testJsFileLoadJsFile(self):
    file_path = self.GetTestFilePath('load_simple_js.js')
    output = d8_runner.ExecuteFile(file_path, source_paths=[self.test_data_dir])
    expected_output = ('bar.js is loaded\n'
                       'load_simple_js.js is loaded\n')
    self.assertEquals(output, expected_output)

  def testHTMLFileLoadHTMLFile(self):
    file_path = self.GetTestFilePath('load_simple_html.html')
    output = d8_runner.ExecuteFile(
        file_path, source_paths=[self.test_data_dir])
    expected_output = ('File foo.html is loaded\n'
                       'x = 1\n'
                       "File foo.html's second script is loaded\n"
                       'x = 2\n'
                       'bar.js is loaded\n'
                       'File load_simple_html.html is loaded\n')
    self.assertEquals(output, expected_output)

  def testQuit0Handling(self):
    file_path = self.GetTestFilePath('quit_0_test.js')
    res = d8_runner.RunFile(file_path, source_paths=[self.test_data_dir])
    self.assertEquals(res.returncode, 0)

  def testQuit1Handling(self):
    file_path = self.GetTestFilePath('quit_1_test.js')
    res = d8_runner.RunFile(file_path, source_paths=[self.test_data_dir])
    self.assertEquals(res.returncode, 1)

  def testQuit42Handling(self):
    file_path = self.GetTestFilePath('quit_42_test.js')
    res = d8_runner.RunFile(file_path, source_paths=[self.test_data_dir])
    self.assertEquals(res.returncode, 42)

  def testQuit274Handling(self):
    file_path = self.GetTestFilePath('quit_274_test.js')
    res = d8_runner.RunFile(file_path, source_paths=[self.test_data_dir])
    self.assertEquals(res.returncode, 238)

  def testErrorStackTraceJs(self):
    file_path = self.GetTestFilePath('error_stack_test.js')
    # error_stack_test.js imports load_simple_html.html
    # load_simple_html.html imports foo.html
    # foo.html imports error.js
    # error.js defines maybeRaiseException() method that can raise exception
    # foo.html defines maybeRaiseExceptionInFoo() method that calls
    # maybeRaiseException()
    # Finally, we call maybeRaiseExceptionInFoo() error_stack_test.js
    # Exception log should capture these method calls' stack trace.
    with self.assertRaises(RuntimeError) as context:
      d8_runner.ExecuteFile(file_path, source_paths=[self.test_data_dir])

    # Assert error stack trace contain src files' info.
    exception_message = context.exception.message
    self.assertIn(
        ('error.js:7: Error: Throw ERROR\n'
         "    throw new Error('Throw ERROR');"), exception_message)
    self.AssertHasNamedFrame('maybeRaiseException', 'error.js:7',
                             exception_message)
    self.AssertHasNamedFrame('global.maybeRaiseExceptionInFoo', 'foo.html:34',
                             exception_message)
    self.AssertHasFrame('error_stack_test.js:14', exception_message)

  def testErrorStackTraceHTML(self):
    file_path = self.GetTestFilePath('error_stack_test.html')
    # error_stack_test.html imports error_stack_test.js
    # error_stack_test.js imports load_simple_html.html
    # load_simple_html.html imports foo.html
    # foo.html imports error.js
    # error.js defines maybeRaiseException() method that can raise exception
    # foo.html defines maybeRaiseExceptionInFoo() method that calls
    # maybeRaiseException()
    # Finally, we call maybeRaiseExceptionInFoo() error_stack_test.js
    # Exception log should capture these method calls' stack trace.
    with self.assertRaises(RuntimeError) as context:
      d8_runner.ExecuteFile(file_path, source_paths=[self.test_data_dir])

    # Assert error stack trace contain src files' info.
    exception_message = context.exception.message
    self.assertIn(
        ('error.js:7: Error: Throw ERROR\n'
         "    throw new Error('Throw ERROR');"), exception_message)

    self.AssertHasNamedFrame('maybeRaiseException', 'error.js:7',
                             exception_message)
    self.AssertHasNamedFrame('global.maybeRaiseExceptionInFoo', 'foo.html:34',
                             exception_message)
    self.AssertHasFrame('error_stack_test.js:14', exception_message)
    self.AssertHasNamedFrame('eval', 'error_stack_test.html:22',
                             exception_message)

  def testStackTraceOfErroWhenLoadingHTML(self):
    file_path = self.GetTestFilePath('load_error.html')
    with self.assertRaises(RuntimeError) as context:
      d8_runner.ExecuteFile(file_path, source_paths=[self.test_data_dir])

    # Assert error stack trace contain src files' info.
    exception_message = context.exception.message

    self.assertIn('Error: /does_not_exist.html not found', exception_message)
    self.AssertHasNamedFrame('eval', 'load_error_2.html:21', exception_message)
    self.AssertHasNamedFrame('eval', 'load_error.html:23', exception_message)

  def testStackTraceOfErroWhenSyntaxErrorOccurs(self):
    file_path = self.GetTestFilePath('syntax_error.html')
    with self.assertRaises(RuntimeError) as context:
      d8_runner.ExecuteFile(file_path, source_paths=[self.test_data_dir])

    # Assert error stack trace contain src files' info.
    exception_message = context.exception.message

    self.assertIn('syntax_error.html:23: SyntaxError: Unexpected identifier',
                  exception_message)

  def testStackTraceOfErroWhenLoadingJS(self):
    file_path = self.GetTestFilePath('load_js_error.html')
    with self.assertRaises(RuntimeError) as context:
      d8_runner.ExecuteFile(file_path, source_paths=[self.test_data_dir])

    # Assert error stack trace contain src files' info.
    exception_message = context.exception.message

    self.assertIn('Error: /does_not_exist.js not found', exception_message)
    self.AssertHasNamedFrame('eval', 'load_js_error_2.html:20',
                             exception_message)
    self.AssertHasNamedFrame('eval', 'load_js_error.html:22',
                             exception_message)

  def testConsolePolyfill(self):
    self.assertEquals(
        d8_runner.ExcecuteJsString('console.log("hello", "world");'),
        'hello world\n')
    self.assertEquals(
        d8_runner.ExcecuteJsString('console.info("hello", "world");'),
        'Info: hello world\n')
    self.assertEquals(
        d8_runner.ExcecuteJsString('console.warn("hello", "world");'),
        'Warning: hello world\n')
    self.assertEquals(
        d8_runner.ExcecuteJsString('console.error("hello", "world");'),
        'Error: hello world\n')


@unittest.skipIf(sys.platform.startswith('win'),
                 'd8 not yet supported on Windows.')
class PathUtilUnittest(unittest.TestCase):
  def testPathUtil(self):
    path_util_js_test = os.path.abspath(os.path.join(
        os.path.dirname(__file__), 'path_utils_test.js'))
    test_loading_js = """
    load('%s');
    load('%s');
    runTests();
    """ % (d8_runner._PATH_UTILS_JS_DIR, path_util_js_test)

    res = d8_runner.RunJsString(test_loading_js)
    self.assertEquals(res.returncode, 0)


def _GetLineNumberOfSubstring(content, substring):
  """ Return the line number of |substring| in |content|."""
  index = content.index(substring)
  return content[:index].count('\n') + 1


def _GenerateLineByLineDiff(actual, expected):
  results = []
  expected_lines = expected.split('\n')
  actual_lines = actual.split('\n')
  max_num_lines = max(len(expected_lines), len(actual_lines))
  results.append('**Actual    : num lines =  %i' % len(actual_lines))
  results.append('**Expected  : num lines = %i' % len(expected_lines))

  for i in xrange(0, max_num_lines):
    expected_current_line = expected_lines[i] if i < len(expected_lines) else ''
    actual_current_line = actual_lines[i] if i < len(actual_lines) else ''
    if actual_current_line == expected_current_line:
      continue
    results.append('================= Line %s ======================' % (i + 1))
    results.append('**Actual    : %s' % repr(actual_current_line))
    results.append('**Expected  : %s' % repr(expected_current_line))
  return '\n'.join(results)


@unittest.skipIf(sys.platform.startswith('win'),
                 'd8 not yet supported on Windows.')
class HTMLGeneratorTest(unittest.TestCase):

  def AssertStringEquals(self, actual, expected):
    if actual != expected:
      message = 'Expected %s but got %s.\n' % (repr(expected), repr(actual))
      message += _GenerateLineByLineDiff(actual, expected)
      self.fail(message)

  def GetGeneratedJs(self, html_text):
    tmp_dir = tempfile.mkdtemp()
    try:
      temp_file_name = os.path.join(tmp_dir, 'test.html')
      with open(temp_file_name, 'w') as f:
        f.write(html_text)
      return d8_runner.ExcecuteJsString(
          'write(generateJsFromHTML(read("%s")));' % temp_file_name)
    finally:
      shutil.rmtree(tmp_dir)

  def testGenerateJsForD8RunnerSimpleHTMLImport(self):
    html = '<link rel="import" href="/base/math.html">'
    expected_js = "loadHTML('/base/math.html');"
    self.AssertStringEquals(self.GetGeneratedJs(html), expected_js)

  def testGenerateJSForD8RunnerImportMultilineHTMLImport(self):
    html = """
          <link rel="import"
          href="/base/math.html">"""
    expected_js = "\nloadHTML('/base/math.html');"
    self.AssertStringEquals(self.GetGeneratedJs(html),
                            expected_js)

  def testGenerateJsForD8RunnerImportSimpleScriptWithSrc(self):
    html = '<script src="/base/math.js"></script>'
    expected_js = "loadScript('/base/math.js');"
    self.AssertStringEquals(self.GetGeneratedJs(html),
                            expected_js)

  def testGenerateJsForD8RunnerImportMultilineScriptWithSrc(self):
    html = """<script
                  type="text/javascript"
                  src="/base/math.js">
                  </script>"""
    expected_js = """loadScript('/base/math.js');


                  """
    self.AssertStringEquals(self.GetGeneratedJs(html),
                            expected_js)

  def testGenerateJsForD8RunnerWithMixedMultipleImport(self):
    html = """
<link rel="import" href="/base.html"><link rel="import" href="/base64.html">
<link rel="import"
            href="/base/math.html"><script
            type="text/javascript"

            src="/base/3d.js">
            </script>

<script src="/base/math.js"></script>

 <link rel="import"
  href="/base/random.html">
"""
    expected_js = ("""
loadHTML('/base.html');loadHTML('/base64.html');
loadHTML('/base/math.html');
loadScript('/base/3d.js');



            """ + """

loadScript('/base/math.js');

loadHTML('/base/random.html');""")
    self.AssertStringEquals(self.GetGeneratedJs(html),
                            expected_js)

  def testGenerateJsForD8RunnerImportWithSimpleContent(self):
    html = """<script>
               var html_lines = [
                '<script>',
                '< /script>',
               ];
    </script>
    """
    expected_js = """
               var html_lines = [
                '<script>',
                '< /script>',
               ];
    """
    self.AssertStringEquals(self.GetGeneratedJs(html),
                            expected_js)

  def testGenerateJsForD8RunnerImportWithEscapedScriptTag(self):
    html = """<script>
var s = ("<") + "<\/script>";
var x = 100;
    </script>
    """
    expected_js = """
var s = ("<") + "<\/script>";
var x = 100;
    """
    self.AssertStringEquals(self.GetGeneratedJs(html),
                            expected_js)

  def testGenerateJsForD8RunnerImportWithSrcAndSimpleContent(self):
    html = """<script
               src="/base.js">var html_lines = [
                '<script>',
                '< /script>',
               ];
    </script>
    """
    expected_js = """loadScript('/base.js');
var html_lines = [
                '<script>',
                '< /script>',
               ];
    """
    self.AssertStringEquals(self.GetGeneratedJs(html),
                            expected_js)

  def testGenerateJsForD8RunnerImportComplex(self):
    html = """<!DOCTYPE html>
<!--
Copyright (c) 2014 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.
-->
        <link rel="import" href="/base/math.html"><script>var x = 1;</script>
        <script src="/base/computer.js">
          var linux = os.system;  // line number of this is 9
        </script>
        <link rel="import" href="/base/physics.html">

        <script>
              var html_lines = [
                '<script>',
                '< /script>',
              ];
              function foo() {
                var y = [
                  1,
                  2,   // line number of this is 21
                  3,
                  4
                ];
              }
        </script>

         <link rel="import" href="/base/this_is_line_28.html">
         <script>
          var i = '<link rel="import" href="/base/math.html">';
         </script>
        """
    expected_js = """





loadHTML('/base/math.html');var x = 1;
loadScript('/base/computer.js');
          var linux = os.system;  // line number of this is 9
        """ + """
loadHTML('/base/physics.html');


              var html_lines = [
                '<script>',
                '< /script>',
              ];
              function foo() {
                var y = [
                  1,
                  2,   // line number of this is 21
                  3,
                  4
                ];
              }
        """ + """

loadHTML('/base/this_is_line_28.html');

          var i = '<link rel="import" href="/base/math.html">';
         """

    generated_js = self.GetGeneratedJs(html)
    self.AssertStringEquals(
        _GetLineNumberOfSubstring(generated_js, '// line number of this is 9'),
        9)
    self.AssertStringEquals(
        _GetLineNumberOfSubstring(generated_js, '// line number of this is 21'),
        21)
    self.AssertStringEquals(
        _GetLineNumberOfSubstring(generated_js, 'this_is_line_28.html'),
        28)
    self.AssertStringEquals(generated_js, expected_js)
