#!/usr/bin/env python
#
# Copyright 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 sys
import subprocess
import os
import argparse

# Registered host based unit tests
# Must have 'host_supported: true'
HOST_TESTS = [
    'bluetooth_test_common',
    'bluetoothtbd_test',
    'net_test_avrcp',
    'net_test_btcore',
    'net_test_types',
    'net_test_btm_iso',
    'net_test_btpackets',
]

SOONG_UI_BASH = 'build/soong/soong_ui.bash'


def str2bool(argument, default=False):
    """ Convert a string to a booleen value. """
    argument = str(argument)
    if argument.lower() in ['0', 'f', 'false', 'off', 'no', 'n']:
        return False
    elif argument.lower() in ['1', 't', 'true', 'on', 'yes', 'y']:
        return True
    return default


def check_dir_exists(dir, dirname):
    if not os.path.isdir(dir):
        print "Couldn't find %s (%s)!" % (dirname, dir)
        sys.exit(0)


def get_output_from_command(cmd):
    try:
        return subprocess.check_output(cmd).strip()
    except subprocess.CalledProcessError as e:
        print 'Failed to call {cmd}, return code {code}'.format(cmd=cmd, code=e.returncode)
        print e
        return None


def get_android_root_or_die():
    value = os.environ.get('ANDROID_BUILD_TOP')
    if not value:
        # Try to find build/soong/soong_ui.bash upwards until root directory
        current_path = os.path.abspath(os.getcwd())
        while current_path and os.path.isdir(current_path):
            soong_ui_bash_path = os.path.join(current_path, SOONG_UI_BASH)
            if os.path.isfile(soong_ui_bash_path):
                # Use value returned from Soong UI instead in case definition to TOP
                # changes in the future
                value = get_output_from_command((soong_ui_bash_path, '--dumpvar-mode', '--abs', 'TOP'))
                break
            parent_path = os.path.abspath(os.path.join(current_path, os.pardir))
            if parent_path == current_path:
                current_path = None
            else:
                current_path = parent_path
        if not value:
            print 'Cannot determine ANDROID_BUILD_TOP'
            sys.exit(1)
    check_dir_exists(value, '$ANDROID_BUILD_TOP')
    return value


def get_android_host_out_or_die():
    value = os.environ.get('ANDROID_HOST_OUT')
    if not value:
        ANDROID_BUILD_TOP = get_android_root_or_die()
        value = get_output_from_command((os.path.join(ANDROID_BUILD_TOP, SOONG_UI_BASH), '--dumpvar-mode', '--abs',
                                         'HOST_OUT'))
        if not value:
            print 'Cannot determine ANDROID_HOST_OUT'
            sys.exit(1)
    check_dir_exists(value, '$ANDROID_HOST_OUT')
    return value


def get_android_dist_dir_or_die():
    # Check if $DIST_DIR is predefined as environment variable
    value = os.environ.get('DIST_DIR')
    if not value:
        # If not use the default path
        ANDROID_BUILD_TOP = get_android_root_or_die()
        value = os.path.join(os.path.join(ANDROID_BUILD_TOP, 'out'), 'dist')
    if not os.path.isdir(value):
        if os.path.exists(value):
            print '%s is not a directory!' % (value)
            sys.exit(1)
        os.makedirs(value)
    return value


def get_native_test_root_or_die():
    android_host_out = get_android_host_out_or_die()
    test_root = os.path.join(android_host_out, 'nativetest64')
    if not os.path.isdir(test_root):
        test_root = os.path.join(android_host_out, 'nativetest')
        if not os.path.isdir(test_root):
            print 'Neither nativetest64 nor nativetest directory exist,' \
                  ' please compile first'
            sys.exit(1)
    return test_root


def get_test_cmd_or_die(test_root, test_name, enable_xml, test_filter):
    test_path = os.path.join(os.path.join(test_root, test_name), test_name)
    if not os.path.isfile(test_path):
        print 'Cannot find: ' + test_path
        sys.exit(1)
    cmd = [test_path]
    if enable_xml:
        dist_dir = get_android_dist_dir_or_die()
        log_output_path = os.path.join(dist_dir, 'gtest/{0}_test_details.xml'.format(test_name))
        cmd.append('--gtest_output=xml:{0}'.format(log_output_path))
    if test_filter:
        cmd.append('--gtest_filter=%s' % test_filter)
    return cmd


# path is relative to Android build top
def build_target(target, num_tasks):
    ANDROID_BUILD_TOP = get_android_root_or_die()
    build_cmd = [SOONG_UI_BASH, '--make-mode']
    if num_tasks > 1:
        build_cmd.append('-j' + str(num_tasks))
    build_cmd.append(target)
    p = subprocess.Popen(build_cmd, cwd=ANDROID_BUILD_TOP, env=os.environ.copy())
    return_code = p.wait()
    if return_code != 0:
        print 'BUILD FAILED, return code: {0}'.format(str(return_code))
        sys.exit(1)
    return


def main():
    """ run_host_unit_tests.py - Run registered host based unit tests
  """
    parser = argparse.ArgumentParser(description='Run host based unit tests.')
    parser.add_argument(
        '--enable_xml',
        type=str2bool,
        dest='enable_xml',
        nargs='?',
        const=True,
        default=False,
        help='Whether to output structured XML log output in out/dist/gtest directory')
    parser.add_argument(
        '-j',
        type=int,
        nargs='?',
        dest='num_tasks',
        const=-1,
        default=-1,
        help='Number of tasks to run at the same time')
    parser.add_argument(
        'rest', nargs=argparse.REMAINDER, help='-- args, other gtest arguments for each individual test')
    args = parser.parse_args()

    build_target('MODULES-IN-system-bt', args.num_tasks)
    TEST_ROOT = get_native_test_root_or_die()
    test_results = []
    for test in HOST_TESTS:
        test_cmd = get_test_cmd_or_die(TEST_ROOT, test, args.enable_xml, args.rest)
        if subprocess.call(test_cmd) != 0:
            test_results.append(False)
        else:
            test_results.append(True)
    if not all(test_results):
        failures = [i for i, x in enumerate(test_results) if not x]
        for index in failures:
            print 'TEST FAILLED: ' + HOST_TESTS[index]
        sys.exit(0)
    print 'TEST PASSED ' + str(len(test_results)) + ' tests were run'

    dist_dir = get_android_dist_dir_or_die()
    log_output_path = os.path.join(dist_dir, 'gtest/coverage')
    cmd_path = os.path.join(get_android_root_or_die(), 'system/bt/test')
    print cmd_path
    cmd = [
        os.path.join(cmd_path, 'gen_coverage.py'),
        '--skip-html',
        '--json-file',
        '-o',
        log_output_path,
    ]
    subprocess.call(cmd)

    sys.exit(0)


if __name__ == '__main__':
    main()
