#!/usr/bin/env python3
# Copyright 2018 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 convert_dex_profile.

Can be run from build/android/:
  $ cd build/android
  $ python convert_dex_profile_tests.py
"""

import os
import sys
import tempfile
import unittest

import convert_dex_profile as cp

sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'gyp'))
from util import build_utils

cp.logging.disable(cp.logging.CRITICAL)

# There are two obfuscations used in the tests below, each with the same
# unobfuscated profile. The first, corresponding to DEX_DUMP, PROGUARD_MAPPING,
# and OBFUSCATED_PROFILE, has an ambiguous method a() which is mapped to both
# getInstance and initialize. The second, corresponding to DEX_DUMP_2,
# PROGUARD_MAPPING_2 and OBFUSCATED_PROFILE_2, removes the ambiguity.

DEX_DUMP = """

Class descriptor  : 'La;'
  Direct methods    -
      #0              : (in La;)
        name          : '<clinit>'
        type          : '(Ljava/lang/String;)V'
        code          -
        catches       : 1
                0x000f - 0x001e
                  <any> -> 0x0093
        positions     :
                0x0001 line=310
                0x0057 line=313
        locals        :
      #1              : (in La;)
        name          : '<init>'
        type          : '()V'
        positions     :
        locals        :
  Virtual methods   -
      #0              : (in La;)
        name          : 'a'
        type          : '(Ljava/lang/String;)I'
        positions     :
          0x0000 line=2
          0x0003 line=3
          0x001b line=8
        locals        :
          0x0000 - 0x0021 reg=3 this La;
      #1              : (in La;)
        name          : 'a'
        type          : '(Ljava/lang/Object;)I'
        positions     :
          0x0000 line=8
          0x0003 line=9
        locals        :
          0x0000 - 0x0021 reg=3 this La;
      #2              : (in La;)
        name          : 'b'
        type          : '()La;'
        positions     :
          0x0000 line=1
        locals        :
"""

# pylint: disable=line-too-long
PROGUARD_MAPPING = \
"""org.chromium.Original -> a:
    org.chromium.Original sDisplayAndroidManager -> e
    org.chromium.Original another() -> b
    4:4:void inlined():237:237 -> a
    4:4:org.chromium.Original getInstance():203 -> a
    5:5:void org.chromium.Original$Subclass.<init>(org.chromium.Original,byte):130:130 -> a
    5:5:void initialize():237 -> a
    5:5:org.chromium.Original getInstance():203 -> a
    6:6:void initialize():237:237 -> a
    9:9:android.content.Context org.chromium.base.ContextUtils.getApplicationContext():49:49 -> a
    9:9:android.content.Context getContext():219 -> a
    9:9:void initialize():245 -> a
    9:9:org.chromium.Original getInstance():203 -> a"""

OBFUSCATED_PROFILE = \
"""La;
PLa;->b()La;
SLa;->a(Ljava/lang/Object;)I
HPLa;->a(Ljava/lang/String;)I"""

DEX_DUMP_2 = """

Class descriptor  : 'La;'
  Direct methods    -
      #0              : (in La;)
        name          : '<clinit>'
        type          : '(Ljava/lang/String;)V'
        code          -
        catches       : 1
                0x000f - 0x001e
                  <any> -> 0x0093
        positions     :
                0x0001 line=310
                0x0057 line=313
        locals        :
      #1              : (in La;)
        name          : '<init>'
        type          : '()V'
        positions     :
        locals        :
  Virtual methods   -
      #0              : (in La;)
        name          : 'a'
        type          : '(Ljava/lang/String;)I'
        positions     :
          0x0000 line=2
          0x0003 line=3
          0x001b line=8
        locals        :
          0x0000 - 0x0021 reg=3 this La;
      #1              : (in La;)
        name          : 'c'
        type          : '(Ljava/lang/Object;)I'
        positions     :
          0x0000 line=8
          0x0003 line=9
        locals        :
          0x0000 - 0x0021 reg=3 this La;
      #2              : (in La;)
        name          : 'b'
        type          : '()La;'
        positions     :
          0x0000 line=1
        locals        :
"""

# pylint: disable=line-too-long
PROGUARD_MAPPING_2 = \
"""org.chromium.Original -> a:
    org.chromium.Original sDisplayAndroidManager -> e
    org.chromium.Original another() -> b
    void initialize() -> c
    org.chromium.Original getInstance():203 -> a
    4:4:void inlined():237:237 -> a"""

OBFUSCATED_PROFILE_2 = \
"""La;
PLa;->b()La;
HPSLa;->a()La;
HPLa;->c()V"""

UNOBFUSCATED_PROFILE = \
"""Lorg/chromium/Original;
PLorg/chromium/Original;->another()Lorg/chromium/Original;
HPSLorg/chromium/Original;->getInstance()Lorg/chromium/Original;
HPLorg/chromium/Original;->initialize()V"""

class GenerateProfileTests(unittest.TestCase):
  def testProcessDex(self):
    dex = cp.ProcessDex(DEX_DUMP.splitlines())
    self.assertIsNotNone(dex['a'])

    self.assertEqual(len(dex['a'].FindMethodsAtLine('<clinit>', 311, 313)), 1)
    self.assertEqual(len(dex['a'].FindMethodsAtLine('<clinit>', 309, 315)), 1)
    clinit = dex['a'].FindMethodsAtLine('<clinit>', 311, 313)[0]
    self.assertEqual(clinit.name, '<clinit>')
    self.assertEqual(clinit.return_type, 'V')
    self.assertEqual(clinit.param_types, 'Ljava/lang/String;')

    self.assertEqual(len(dex['a'].FindMethodsAtLine('a', 8, None)), 2)
    self.assertIsNone(dex['a'].FindMethodsAtLine('a', 100, None))

# pylint: disable=protected-access
  def testProcessProguardMapping(self):
    dex = cp.ProcessDex(DEX_DUMP.splitlines())
    mapping, reverse = cp.ProcessProguardMapping(
        PROGUARD_MAPPING.splitlines(), dex)

    self.assertEqual('La;', reverse.GetClassMapping('Lorg/chromium/Original;'))

    getInstance = cp.Method(
        'getInstance', 'Lorg/chromium/Original;', '', 'Lorg/chromium/Original;')
    initialize = cp.Method('initialize', 'Lorg/chromium/Original;', '', 'V')
    another = cp.Method(
        'another', 'Lorg/chromium/Original;', '', 'Lorg/chromium/Original;')
    subclassInit = cp.Method(
        '<init>', 'Lorg/chromium/Original$Subclass;',
        'Lorg/chromium/Original;B', 'V')

    mapped = mapping.GetMethodMapping(
        cp.Method('a', 'La;', 'Ljava/lang/String;', 'I'))
    self.assertEqual(len(mapped), 2)
    self.assertIn(getInstance, mapped)
    self.assertNotIn(subclassInit, mapped)
    self.assertNotIn(
        cp.Method('inlined', 'Lorg/chromium/Original;', '', 'V'), mapped)
    self.assertIn(initialize, mapped)

    mapped = mapping.GetMethodMapping(
        cp.Method('a', 'La;', 'Ljava/lang/Object;', 'I'))
    self.assertEqual(len(mapped), 1)
    self.assertIn(getInstance, mapped)

    mapped = mapping.GetMethodMapping(cp.Method('b', 'La;', '', 'La;'))
    self.assertEqual(len(mapped), 1)
    self.assertIn(another, mapped)

    for from_method, to_methods in mapping._method_mapping.items():
      for to_method in to_methods:
        self.assertIn(from_method, reverse.GetMethodMapping(to_method))
    for from_class, to_class in mapping._class_mapping.items():
      self.assertEqual(from_class, reverse.GetClassMapping(to_class))

  def testProcessProfile(self):
    dex = cp.ProcessDex(DEX_DUMP.splitlines())
    mapping, _ = cp.ProcessProguardMapping(PROGUARD_MAPPING.splitlines(), dex)
    profile = cp.ProcessProfile(OBFUSCATED_PROFILE.splitlines(), mapping)

    getInstance = cp.Method(
        'getInstance', 'Lorg/chromium/Original;', '', 'Lorg/chromium/Original;')
    initialize = cp.Method('initialize', 'Lorg/chromium/Original;', '', 'V')
    another = cp.Method(
        'another', 'Lorg/chromium/Original;', '', 'Lorg/chromium/Original;')

    self.assertIn('Lorg/chromium/Original;', profile._classes)
    self.assertIn(getInstance, profile._methods)
    self.assertIn(initialize, profile._methods)
    self.assertIn(another, profile._methods)

    self.assertEqual(profile._methods[getInstance], set(['H', 'S', 'P']))
    self.assertEqual(profile._methods[initialize], set(['H', 'P']))
    self.assertEqual(profile._methods[another], set(['P']))

  def testEndToEnd(self):
    dex = cp.ProcessDex(DEX_DUMP.splitlines())
    mapping, _ = cp.ProcessProguardMapping(PROGUARD_MAPPING.splitlines(), dex)

    profile = cp.ProcessProfile(OBFUSCATED_PROFILE.splitlines(), mapping)
    with tempfile.NamedTemporaryFile() as temp:
      profile.WriteToFile(temp.name)
      with open(temp.name, 'r') as f:
        for a, b in zip(sorted(f), sorted(UNOBFUSCATED_PROFILE.splitlines())):
          self.assertEqual(a.strip(), b.strip())

  def testObfuscateProfile(self):
    with build_utils.TempDir() as temp_dir:
      # The dex dump is used as the dexfile, by passing /bin/cat as the dexdump
      # program.
      dex_path = os.path.join(temp_dir, 'dexdump')
      with open(dex_path, 'w') as dex_file:
        dex_file.write(DEX_DUMP_2)
      mapping_path = os.path.join(temp_dir, 'mapping')
      with open(mapping_path, 'w') as mapping_file:
        mapping_file.write(PROGUARD_MAPPING_2)
      unobfuscated_path = os.path.join(temp_dir, 'unobfuscated')
      with open(unobfuscated_path, 'w') as unobfuscated_file:
        unobfuscated_file.write(UNOBFUSCATED_PROFILE)
      obfuscated_path = os.path.join(temp_dir, 'obfuscated')
      cp.ObfuscateProfile(unobfuscated_path, dex_path, mapping_path, '/bin/cat',
                          obfuscated_path)
      with open(obfuscated_path) as obfuscated_file:
        obfuscated_profile = sorted(obfuscated_file.readlines())
      for a, b in zip(
          sorted(OBFUSCATED_PROFILE_2.splitlines()), obfuscated_profile):
        self.assertEqual(a.strip(), b.strip())


if __name__ == '__main__':
  unittest.main()
