#!/usr/bin/env python
#
# Copyright (C) 2016 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.
#
"""Runs the test suite over a set of devices."""
from __future__ import print_function

import argparse
import distutils.spawn
import os
import re
import shutil
import signal
import site
import subprocess
import sys
import tempfile

import ndk.debug


THIS_DIR = os.path.realpath(os.path.dirname(__file__))


class Device(object):
    def __init__(self, serial, name, version, build_id, abis, is_emulator):
        self.serial = serial
        self.name = name
        self.version = version
        self.build_id = build_id
        self.abis = abis
        self.is_emulator = is_emulator

    def __str__(self):
        return 'android-{} {} {} {}'.format(
            self.version, self.name, self.serial, self.build_id)


class DeviceFleet(object):
    def __init__(self):
        self.devices = {
            10: {
                'armeabi': None,
                'armeabi-v7a': None,
            },
            16: {
                'armeabi': None,
                'armeabi-v7a': None,
                'x86': None,
            },
            23: {
                'armeabi': None,
                'armeabi-v7a': None,
                'arm64-v8a': None,
                'x86': None,
                'x86_64': None,
            },
        }

    def add_device(self, device):
        if device.version not in self.devices:
            print('Ignoring device for unwanted API level: {}'.format(device))
            return

        same_version = self.devices[device.version]
        for abi, current_device in same_version.iteritems():
            # This device can't fulfill this ABI.
            if abi not in device.abis:
                continue

            # Anything is better than nothing.
            if current_device is None:
                self.devices[device.version][abi] = device
                continue

            # The emulator images have actually been changed over time, so the
            # devices are more trustworthy.
            if current_device.is_emulator and not device.is_emulator:
                self.devices[device.version][abi] = device

    def get_device(self, version, abi):
        return self.devices[version][abi]

    def get_missing(self):
        missing = []
        for version, abis in self.devices.iteritems():
            for abi, device in abis.iteritems():
                if device is None:
                    missing.append('android-{} {}'.format(version, abi))
        return missing

    def get_versions(self):
        return self.devices.keys()

    def get_abis(self, version):
        return self.devices[version].keys()


def get_device_abis(properties):
    # 64-bit devices list their ABIs differently than 32-bit devices. Check all
    # the possible places for stashing ABI info and merge them.
    abi_properties = [
        'ro.product.cpu.abi',
        'ro.product.cpu.abi2',
        'ro.product.cpu.abilist',
    ]
    abis = set()
    for abi_prop in abi_properties:
        if abi_prop in properties:
            abis.update(properties[abi_prop].split(','))

    return sorted(list(abis))


def get_device_details(serial):
    import adb  # pylint: disable=import-error
    props = adb.get_device(serial).get_props()
    name = props['ro.product.name']
    version = int(props['ro.build.version.sdk'])
    supported_abis = get_device_abis(props)
    build_id = props['ro.build.id']
    is_emulator = props.get('ro.build.characteristics') == 'emulator'
    return Device(serial, name, version, build_id, supported_abis, is_emulator)


def find_devices():
    """Detects connected devices and returns a set for testing.

    We get a list of devices by scanning the output of `adb devices`. We want
    to run the tests for the cross product of the following configurations:

    ABIs: {armeabi, armeabi-v7a, arm64-v8a, mips, mips64, x86, x86_64}
    Platform versions: {android-10, android-16, android-21}
    Toolchains: {clang, gcc}

    Note that not all ABIs are available for every platform version. There are
    no 64-bit ABIs before android-21, and there were no MIPS ABIs for
    android-10.
    """
    if distutils.spawn.find_executable('adb') is None:
        raise RuntimeError('Could not find adb.')

    # We could get the device name from `adb devices -l`, but we need to
    # getprop to find other details anyway, and older devices don't report
    # their names properly (nakasi on android-16, for example).
    p = subprocess.Popen(['adb', 'devices'], stdout=subprocess.PIPE)
    out, _ = p.communicate()
    if p.returncode != 0:
        raise RuntimeError('Failed to get list of devices from adb.')

    # The first line of `adb devices` just says "List of attached devices", so
    # skip that.
    fleet = DeviceFleet()
    for line in out.split('\n')[1:]:
        if not line.strip():
            continue

        serial, _ = re.split(r'\s+', line, maxsplit=1)

        if 'offline' in line:
            print('Ignoring offline device: ' + serial)
            continue
        if 'unauthorized' in line:
            print('Ignoring unauthorized device: ' + serial)
            continue

        device = get_device_details(serial)
        print('Found device {}'.format(device))
        fleet.add_device(device)

    return fleet


def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        'ndk', metavar='NDK', type=os.path.realpath, help='NDK to validate.')
    parser.add_argument(
        '--filter', help='Only run tests that match the given pattern.')
    parser.add_argument(
        '--log-dir', type=os.path.realpath, default='test-logs',
        help='Directory to store test logs.')

    return parser.parse_args()


def get_aggregate_results(details):
    tests = {}
    for version, abis in details.iteritems():
        for abi, toolchains in abis.iteritems():
            for toolchain, results in toolchains.iteritems():
                for suite, test_results in results.iteritems():
                    for test in test_results:
                        if test.failed():
                            name = '.'.join([suite, test.test_name])
                            if name not in tests:
                                tests[name] = []
                            tests[name].append((version, abi, toolchain, test))
    return tests


def print_aggregate_details(details, use_color):
    tests = get_aggregate_results(details)
    for test_name, configs in tests.iteritems():
        # We might be printing a lot of crap here, so let's be obvious about
        # where each test starts.
        print('BEGIN TEST RESULT: ' + test_name)
        print('=' * 80)

        for version, abi, toolchain, result in configs:
            print('FAILED {} {} {}:'.format(toolchain, abi, version))
            print(result.to_string(colored=use_color))


def main():
    if sys.platform != 'win32':
        ndk.debug.register_debug_handler(signal.SIGUSR1)
        ndk.debug.register_trace_handler(signal.SIGUSR2)

    args = parse_args()

    os.chdir(THIS_DIR)

    # We need to do this here rather than at the top because we load the module
    # from a path that is given on the command line. We load it from the NDK
    # given on the command line so this script can be run even without a full
    # platform checkout.
    site.addsitedir(os.path.join(args.ndk, 'python-packages'))

    ndk_build_path = os.path.join(args.ndk, 'ndk-build')
    if os.name == 'nt':
        ndk_build_path += '.cmd'
    if not os.path.exists(ndk_build_path):
        sys.exit(ndk_build_path + ' does not exist.')

    fleet = find_devices()
    print('Test configuration:')
    for version in sorted(fleet.get_versions()):
        print('\tandroid-{}:'.format(version))
        for abi in sorted(fleet.get_abis(version)):
            print('\t\t{}: {}'.format(abi, fleet.get_device(version, abi)))
    missing_configs = fleet.get_missing()
    if len(missing_configs):
        print('Missing configurations: {}'.format(', '.join(missing_configs)))

    if os.path.exists(args.log_dir):
        shutil.rmtree(args.log_dir)
    os.makedirs(args.log_dir)

    use_color = sys.stdin.isatty() and os.name != 'nt'
    out_dir = tempfile.mkdtemp()
    try:
        import tests.runners
        good, details = tests.runners.run_for_fleet(
            args.ndk, fleet, out_dir, args.log_dir, args.filter, use_color)
    finally:
        shutil.rmtree(out_dir)

    print_aggregate_details(details, use_color)

    sys.exit(not good)


if __name__ == '__main__':
    main()
