#!/usr/bin/python3
#
# Build performance test script
#
# Copyright (c) 2016, Intel Corporation.
#
# SPDX-License-Identifier: GPL-2.0-only
#

import argparse
import errno
import fcntl
import json
import logging
import os
import re
import shutil
import sys
from datetime import datetime

sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + '/lib')
import scriptpath
scriptpath.add_oe_lib_path()
scriptpath.add_bitbake_lib_path()
import oeqa.buildperf
from oeqa.buildperf import (BuildPerfTestLoader, BuildPerfTestResult,
                            BuildPerfTestRunner, KernelDropCaches)
from oeqa.utils.commands import runCmd
from oeqa.utils.metadata import metadata_from_bb, write_metadata_file


# Set-up logging
LOG_FORMAT = '[%(asctime)s] %(levelname)s: %(message)s'
logging.basicConfig(level=logging.INFO, format=LOG_FORMAT,
                    datefmt='%Y-%m-%d %H:%M:%S')
log = logging.getLogger()


def acquire_lock(lock_f):
    """Acquire flock on file"""
    log.debug("Acquiring lock %s", os.path.abspath(lock_f.name))
    try:
        fcntl.flock(lock_f, fcntl.LOCK_EX | fcntl.LOCK_NB)
    except IOError as err:
        if err.errno == errno.EAGAIN:
            return False
        raise
    log.debug("Lock acquired")
    return True


def pre_run_sanity_check():
    """Sanity check of build environment"""
    build_dir = os.environ.get("BUILDDIR")
    if not build_dir:
        log.error("BUILDDIR not set. Please run the build environmnent setup "
                  "script.")
        return False
    if os.getcwd() != build_dir:
        log.error("Please run this script under BUILDDIR (%s)", build_dir)
        return False

    ret = runCmd('which bitbake', ignore_status=True)
    if ret.status:
        log.error("bitbake command not found")
        return False
    return True

def setup_file_logging(log_file):
    """Setup loggin to file"""
    log_dir = os.path.dirname(log_file)
    if not os.path.exists(log_dir):
        os.makedirs(log_dir)
    formatter = logging.Formatter(LOG_FORMAT)
    handler = logging.FileHandler(log_file)
    handler.setFormatter(formatter)
    log.addHandler(handler)


def archive_build_conf(out_dir):
    """Archive build/conf to test results"""
    src_dir = os.path.join(os.environ['BUILDDIR'], 'conf')
    tgt_dir = os.path.join(out_dir, 'build', 'conf')
    os.makedirs(os.path.dirname(tgt_dir))
    shutil.copytree(src_dir, tgt_dir)


def update_globalres_file(result_obj, filename, metadata):
    """Write results to globalres csv file"""
    # Map test names to time and size columns in globalres
    # The tuples represent index and length of times and sizes
    # respectively
    gr_map = {'test1': ((0, 1), (8, 1)),
              'test12': ((1, 1), (None, None)),
              'test13': ((2, 1), (9, 1)),
              'test2': ((3, 1), (None, None)),
              'test3': ((4, 3), (None, None)),
              'test4': ((7, 1), (10, 2))}

    values = ['0'] * 12
    for status, test, _ in result_obj.all_results():
        if status in ['ERROR', 'SKIPPED']:
            continue
        (t_ind, t_len), (s_ind, s_len) = gr_map[test.name]
        if t_ind is not None:
            values[t_ind:t_ind + t_len] = test.times
        if s_ind is not None:
            values[s_ind:s_ind + s_len] = test.sizes

    log.debug("Writing globalres log to %s", filename)
    rev_info = metadata['layers']['meta']
    with open(filename, 'a') as fobj:
        fobj.write('{},{}:{},{},'.format(metadata['hostname'],
                                         rev_info['branch'],
                                         rev_info['commit'],
                                         rev_info['commit']))
        fobj.write(','.join(values) + '\n')


def parse_args(argv):
    """Parse command line arguments"""
    parser = argparse.ArgumentParser(
        formatter_class=argparse.ArgumentDefaultsHelpFormatter)

    parser.add_argument('-D', '--debug', action='store_true',
                        help='Enable debug level logging')
    parser.add_argument('--globalres-file',
                        type=os.path.abspath,
                        help="Append results to 'globalres' csv file")
    parser.add_argument('--lock-file', default='./oe-build-perf.lock',
                        metavar='FILENAME', type=os.path.abspath,
                        help="Lock file to use")
    parser.add_argument('-o', '--out-dir', default='results-{date}',
                        type=os.path.abspath,
                        help="Output directory for test results")
    parser.add_argument('-x', '--xml', action='store_true',
                        help='Enable JUnit xml output')
    parser.add_argument('--log-file',
                        default='{out_dir}/oe-build-perf-test.log',
                        help="Log file of this script")
    parser.add_argument('--run-tests', nargs='+', metavar='TEST',
                        help="List of tests to run")

    return parser.parse_args(argv)


def main(argv=None):
    """Script entry point"""
    args = parse_args(argv)

    # Set-up log file
    out_dir = args.out_dir.format(date=datetime.now().strftime('%Y%m%d%H%M%S'))
    setup_file_logging(args.log_file.format(out_dir=out_dir))

    if args.debug:
        log.setLevel(logging.DEBUG)

    lock_f = open(args.lock_file, 'w')
    if not acquire_lock(lock_f):
        log.error("Another instance of this script is running, exiting...")
        return 1

    if not pre_run_sanity_check():
        return 1

    # Check our capability to drop caches and ask pass if needed
    KernelDropCaches.check()

    # Load build perf tests
    loader = BuildPerfTestLoader()
    if args.run_tests:
        suite = loader.loadTestsFromNames(args.run_tests, oeqa.buildperf)
    else:
        suite = loader.loadTestsFromModule(oeqa.buildperf)

    # Save test metadata
    metadata = metadata_from_bb()
    log.info("Testing Git revision branch:commit %s:%s (%s)",
             metadata['layers']['meta']['branch'],
             metadata['layers']['meta']['commit'],
             metadata['layers']['meta']['commit_count'])
    if args.xml:
        write_metadata_file(os.path.join(out_dir, 'metadata.xml'), metadata)
    else:
        with open(os.path.join(out_dir, 'metadata.json'), 'w') as fobj:
            json.dump(metadata, fobj, indent=2)
    archive_build_conf(out_dir)

    runner = BuildPerfTestRunner(out_dir, verbosity=2)

    # Suppress logger output to stderr so that the output from unittest
    # is not mixed with occasional logger output
    log.handlers[0].setLevel(logging.CRITICAL)

    # Run actual tests
    result = runner.run(suite)

    # Restore logger output to stderr
    log.handlers[0].setLevel(log.level)

    if args.xml:
        result.write_results_xml()
    else:
        result.write_results_json()
    result.write_buildstats_json()
    if args.globalres_file:
        update_globalres_file(result, args.globalres_file, metadata)
    if result.wasSuccessful():
        return 0

    return 2


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

