#!/usr/bin/env python
# Copyright (C) 2017 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import argparse
import os
import re
import functools
import logging
import subprocess
import sys
import tempfile
import time


""" Runs a test executable on Android.

Takes care of pushing the extra shared libraries that might be required by
some sanitizers. Propagates the test return code to the host, exiting with
0 only if the test execution succeeds on the device.
"""

ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
ADB_PATH = os.path.join(ROOT_DIR, 'buildtools/android_sdk/platform-tools/adb')


def RetryOn(exc_type=(), returns_falsy=False, retries=5):
  """Decorator to retry a function in case of errors or falsy values.

  Implements exponential backoff between retries.

  Args:
    exc_type: Type of exceptions to catch and retry on. May also pass a tuple
      of exceptions to catch and retry on any of them. Defaults to catching no
      exceptions at all.
    returns_falsy: If True then the function will be retried until it stops
      returning a "falsy" value (e.g. None, False, 0, [], etc.). If equal to
      'raise' and the function keeps returning falsy values after all retries,
      then the decorator will raise a ValueError.
    retries: Max number of retry attempts. After exhausting that number of
      attempts the function will be called with no safeguards: any exceptions
      will be raised and falsy values returned to the caller (except when
      returns_falsy='raise').
  """
  def Decorator(f):
    @functools.wraps(f)
    def Wrapper(*args, **kwargs):
      wait = 1
      this_retries = kwargs.pop('retries', retries)
      for _ in range(this_retries):
        retry_reason = None
        try:
          value = f(*args, **kwargs)
        except exc_type as exc:
          retry_reason = 'raised %s' % type(exc).__name__
        if retry_reason is None:
          if returns_falsy and not value:
            retry_reason = 'returned %r' % value
          else:
            return value  # Success!
        print('{} {}, will retry in {} second{} ...'.format(
            f.__name__, retry_reason, wait, '' if wait == 1 else 's'))
        time.sleep(wait)
        wait *= 2
      value = f(*args, **kwargs)  # Last try to run with no safeguards.
      if returns_falsy == 'raise' and not value:
        raise ValueError('%s returned %r' % (f.__name__, value))
      return value
    return Wrapper
  return Decorator


def AdbCall(*args):
  cmd = [ADB_PATH] + list(args)
  print '> adb ' + ' '.join(args)
  return subprocess.check_call(cmd)


def GetProp(prop):
  cmd = [ADB_PATH, 'shell', 'getprop', prop]
  print '> adb ' + ' '.join(cmd)
  output = subprocess.check_output(cmd)
  lines = output.splitlines()
  assert len(lines) == 1, 'Expected output to have one line: {}'.format(output)
  print lines[0]
  return lines[0]


@RetryOn([subprocess.CalledProcessError], returns_falsy=True, retries=10)
def WaitForBootCompletion():
  return GetProp('sys.boot_completed') == '1'


def EnumerateDataDeps():
  with open(os.path.join(ROOT_DIR, 'tools', 'test_data.txt')) as f:
    lines = f.readlines()
  for line in (line.strip() for line in lines if not line.startswith('#')):
    assert os.path.exists(line), line
    yield line


def Main():
  parser = argparse.ArgumentParser()
  parser.add_argument('--no-cleanup', '-n', action='store_true')
  parser.add_argument('--no-data-deps', '-x', action='store_true')
  parser.add_argument('--env', '-e', action='append')
  parser.add_argument('out_dir', help='out/android/')
  parser.add_argument('test_name', help='perfetto_unittests')
  parser.add_argument('cmd_args', nargs=argparse.REMAINDER)
  args = parser.parse_args()

  test_bin = os.path.join(args.out_dir, args.test_name)
  assert os.path.exists(test_bin)

  print 'Waiting for device ...'
  AdbCall('wait-for-device')
  # WaitForBootCompletion()
  AdbCall('root')
  AdbCall('wait-for-device')

  target_dir = '/data/local/tmp/' + args.test_name
  AdbCall('shell', 'rm -rf "%s"; mkdir -p "%s"' % (2 * (target_dir,)))
  # Some tests require the trace directory to exist, while true for android
  # devices in general some emulators might not have it set up. So we check to
  # see if it exists, and if not create it.
  trace_dir = '/data/misc/perfetto-traces'
  AdbCall('shell', 'test -d "%s" || mkdir -p "%s"' % (2 * (trace_dir,)))
  AdbCall('shell', 'rm -rf "%s/*";  ' % trace_dir)
  AdbCall('shell', 'mkdir -p /data/nativetest')
  # This needs to go into /data/nativetest in order to have the system linker
  # namespace applied, which we need in order to link libdexfile_external.so.
  # This gets linked into our tests via libundwindstack.so.
  #
  # See https://android.googlesource.com/platform/system/core/+/master/rootdir/etc/ld.config.txt.
  AdbCall('push', test_bin, "/data/nativetest")

  if not args.no_data_deps:
    for dep in EnumerateDataDeps():
      AdbCall('push', os.path.join(ROOT_DIR, dep), target_dir + '/' + dep)

  # LLVM sanitizers require to sideload a libclangrtXX.so on the device.
  sanitizer_libs = os.path.join(args.out_dir, 'sanitizer_libs')
  env = ' '.join(args.env if args.env is not None else []) + ' '
  if os.path.exists(sanitizer_libs):
    AdbCall('push', sanitizer_libs, target_dir)
    env += 'LD_LIBRARY_PATH="%s/sanitizer_libs" ' % (target_dir)
  cmd = 'cd %s;' % target_dir;
  binary = env + '/data/nativetest/%s' % args.test_name
  cmd += binary
  if args.cmd_args:
    actual_args = [arg.replace(args.test_name, binary) for arg in args.cmd_args]
    cmd += ' ' + ' '.join(actual_args)
  cmd += ';echo -e "\\nTEST_RET_CODE=$?"'
  print cmd
  test_output = subprocess.check_output([ADB_PATH, 'shell', cmd])
  print test_output
  retcode = re.search(r'^TEST_RET_CODE=(\d)', test_output, re.MULTILINE)
  assert retcode, 'Could not find TEST_RET_CODE=N marker'
  retcode = int(retcode.group(1))
  if not args.no_cleanup:
    AdbCall('shell', 'rm -rf "%s"' % target_dir)
  return retcode


if __name__ == '__main__':
  sys.exit(Main())
