#!/usr/bin/env python
#
# Copyright 2017 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.
"""Tests for java_deobfuscate."""

import argparse
import os
import subprocess
import sys
import tempfile
import unittest

# Set by command-line argument.
_JAVA_DEOBFUSCATE_PATH = None

LINE_PREFIXES = [
    '',
    # logcat -v threadtime
    '09-08 14:38:35.535 18029 18084 E qcom_sensors_hal: ',
    # logcat
    'W/GCM     (15158): ',
    'W/GCM     (  158): ',
]

TEST_MAP = """\
this.was.Deobfuscated -> FOO:
    int[] mFontFamily -> a
    1:3:void someMethod(int,android.os.Bundle):65:67 -> bar
never.Deobfuscated -> NOTFOO:
    int[] mFontFamily -> a
    1:3:void someMethod(int,android.os.Bundle):65:67 -> bar
"""

TEST_DATA = [
    "FOO",
    "FOO.bar",
    "Here is a FOO",
    "Here is a FOO baz",
    "Here is a \"FOO\" baz",
    "Here is a \"FOO.bar\" baz",
    "Here it is: FOO",
    "Here it is: FOO.bar",
    "SomeError: SomeFrameworkClass in isTestClass for FOO",
    "Here is a FOO.bar",
    "Here is a FOO.bar baz",
    "END FOO#bar",
    "new-instance 3810 (LSome/Framework/Class;) in LFOO;",
    "FOO: Error message",
    "Caused by: FOO: Error message",
    "\tat FOO.bar(PG:1)",
    "\t at\t FOO.bar\t (\t PG:\t 1\t )",
    ("Unable to start activity ComponentInfo{garbage.in/here.test}:"
     " java.lang.NullPointerException: Attempt to invoke interface method 'void"
     " FOO.bar(int,android.os.Bundle)' on a null object reference"),
    ("Caused by: java.lang.NullPointerException: Attempt to read from field"
     " 'int[] FOO.a' on a null object reference"),
    "java.lang.VerifyError: FOO",
    ('java.lang.NoSuchFieldError: No instance field a of type '
     'Ljava/lang/Class; in class LFOO;'),
    "NOTFOO: Object of type FOO was not destroyed...",
]

EXPECTED_OUTPUT = [
    "this.was.Deobfuscated",
    "this.was.Deobfuscated.someMethod",
    "Here is a this.was.Deobfuscated",
    "Here is a FOO baz",
    "Here is a \"this.was.Deobfuscated\" baz",
    "Here is a \"this.was.Deobfuscated.someMethod\" baz",
    "Here it is: this.was.Deobfuscated",
    "Here it is: this.was.Deobfuscated.someMethod",
    "SomeError: SomeFrameworkClass in isTestClass for this.was.Deobfuscated",
    "Here is a this.was.Deobfuscated.someMethod",
    "Here is a FOO.bar baz",
    "END this.was.Deobfuscated#someMethod",
    "new-instance 3810 (LSome/Framework/Class;) in Lthis/was/Deobfuscated;",
    "this.was.Deobfuscated: Error message",
    "Caused by: this.was.Deobfuscated: Error message",
    "\tat this.was.Deobfuscated.someMethod(Deobfuscated.java:65)",
    ("\t at\t this.was.Deobfuscated.someMethod\t "
     "(\t Deobfuscated.java:\t 65\t )"),
    ("Unable to start activity ComponentInfo{garbage.in/here.test}:"
     " java.lang.NullPointerException: Attempt to invoke interface method"
     " 'void this.was.Deobfuscated.someMethod(int,android.os.Bundle)' on a null"
     " object reference"),
    ("Caused by: java.lang.NullPointerException: Attempt to read from field"
     " 'int[] this.was.Deobfuscated.mFontFamily' on a null object reference"),
    'java.lang.VerifyError: this.was.Deobfuscated',
    ('java.lang.NoSuchFieldError: No instance field mFontFamily of type '
     'Ljava/lang/Class; in class Lthis/was/Deobfuscated;'),
    "NOTFOO: Object of type this.was.Deobfuscated was not destroyed...",
]
TEST_DATA = [s + "\n" for s in TEST_DATA]
EXPECTED_OUTPUT = [s + "\n" for s in EXPECTED_OUTPUT]


class JavaDeobfuscateTest(unittest.TestCase):

  def __init__(self, *args, **kwargs):
    super(JavaDeobfuscateTest, self).__init__(*args, **kwargs)
    self._map_file = None

  def setUp(self):
    self._map_file = tempfile.NamedTemporaryFile()
    self._map_file.write(TEST_MAP)
    self._map_file.flush()

  def tearDown(self):
    if self._map_file:
      self._map_file.close()

  def _testImpl(self, input_lines=None, expected_output_lines=None,
                prefix=''):
    self.assertTrue(bool(input_lines) == bool(expected_output_lines))

    if not input_lines:
      input_lines = [prefix + x for x in TEST_DATA]
    if not expected_output_lines:
      expected_output_lines = [prefix + x for x in EXPECTED_OUTPUT]

    cmd = [_JAVA_DEOBFUSCATE_PATH, self._map_file.name]
    proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
    proc_output, _ = proc.communicate(''.join(input_lines))
    actual_output_lines = proc_output.splitlines(True)
    for actual, expected in zip(actual_output_lines, expected_output_lines):
      self.assertTrue(
          actual == expected or actual.replace('bar', 'someMethod') == expected,
          msg=''.join([
              'Deobfuscation failed.\n',
              '  actual:   %s' % actual,
              '  expected: %s' % expected]))

  def testNoPrefix(self):
    self._testImpl(prefix='')

  def testThreadtimePrefix(self):
    self._testImpl(prefix='09-08 14:38:35.535 18029 18084 E qcom_sensors_hal: ')

  def testStandardPrefix(self):
    self._testImpl(prefix='W/GCM     (15158): ')

  def testStandardPrefixWithPadding(self):
    self._testImpl(prefix='W/GCM     (  158): ')

  @unittest.skip('causes java_deobfuscate to hang, see crbug.com/876539')
  def testIndefiniteHang(self):
    # Test for crbug.com/876539.
    self._testImpl(
        input_lines=[
            'VFY: unable to resolve virtual method 2: LFOO;'
                + '.onDescendantInvalidated '
                + '(Landroid/view/View;Landroid/view/View;)V',
        ],
        expected_output_lines=[
            'VFY: unable to resolve virtual method 2: Lthis.was.Deobfuscated;'
                + '.onDescendantInvalidated '
                + '(Landroid/view/View;Landroid/view/View;)V',
        ])


if __name__ == '__main__':
  parser = argparse.ArgumentParser()
  parser.add_argument('--java-deobfuscate-path', type=os.path.realpath,
                      required=True)
  known_args, unittest_args = parser.parse_known_args()
  _JAVA_DEOBFUSCATE_PATH = known_args.java_deobfuscate_path
  unittest_args = [sys.argv[0]] + unittest_args
  unittest.main(argv=unittest_args)
