#!/usr/bin/env vpython
#
# 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 class FOO',
    'Here is a class FOO baz',
    'Here is a "FOO" baz',
    'Here is a type "FOO" baz',
    'Here is a "FOO.bar" baz',
    '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 FOO',
    'Here is a class this.was.Deobfuscated',
    'Here is a class FOO baz',
    'Here is a "FOO" baz',
    'Here is a type "this.was.Deobfuscated" baz',
    'Here is a "this.was.Deobfuscated.someMethod" baz',
    '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)
