#!/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 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)
