#
# Copyright (C) 2017 Intel Corporation
#
# SPDX-License-Identifier: MIT
#

import os
import time
import glob
import sys
import importlib
import subprocess
import unittest
from random import choice

import oeqa
import oe
import bb.utils

from oeqa.core.context import OETestContext, OETestContextExecutor
from oeqa.core.exception import OEQAPreRun, OEQATestNotFound

from oeqa.utils.commands import runCmd, get_bb_vars, get_test_layer

class NonConcurrentTestSuite(unittest.TestSuite):
    def __init__(self, suite, processes, setupfunc, removefunc):
        super().__init__([suite])
        self.processes = processes
        self.suite = suite
        self.setupfunc = setupfunc
        self.removefunc = removefunc

    def run(self, result):
        (builddir, newbuilddir) = self.setupfunc("-st", None, self.suite)
        ret = super().run(result)
        os.chdir(builddir)
        if newbuilddir and ret.wasSuccessful() and self.removefunc:
            self.removefunc(newbuilddir)

def removebuilddir(d):
    delay = 5
    while delay and (os.path.exists(d + "/bitbake.lock") or os.path.exists(d + "/cache/hashserv.db-wal")):
        time.sleep(1)
        delay = delay - 1
    # Deleting these directories takes a lot of time, use autobuilder
    # clobberdir if its available
    clobberdir = os.path.expanduser("~/yocto-autobuilder-helper/janitor/clobberdir")
    if os.path.exists(clobberdir):
        try:
            subprocess.check_call([clobberdir, d])
            return
        except subprocess.CalledProcessError:
            pass
    bb.utils.prunedir(d, ionice=True)

class OESelftestTestContext(OETestContext):
    def __init__(self, td=None, logger=None, machines=None, config_paths=None, newbuilddir=None, keep_builddir=None):
        super(OESelftestTestContext, self).__init__(td, logger)

        self.machines = machines
        self.custommachine = None
        self.config_paths = config_paths
        self.newbuilddir = newbuilddir

        if keep_builddir:
            self.removebuilddir = None
        else:
            self.removebuilddir = removebuilddir

    def setup_builddir(self, suffix, selftestdir, suite):
        builddir = os.environ['BUILDDIR']
        if not selftestdir:
            selftestdir = get_test_layer()
        if self.newbuilddir:
            newbuilddir = os.path.join(self.newbuilddir, 'build' + suffix)
        else:
            newbuilddir = builddir + suffix
        newselftestdir = newbuilddir + "/meta-selftest"

        if os.path.exists(newbuilddir):
            self.logger.error("Build directory %s already exists, aborting" % newbuilddir)
            sys.exit(1)

        bb.utils.mkdirhier(newbuilddir)
        oe.path.copytree(builddir + "/conf", newbuilddir + "/conf")
        oe.path.copytree(builddir + "/cache", newbuilddir + "/cache")
        oe.path.copytree(selftestdir, newselftestdir)

        for e in os.environ:
            if builddir + "/" in os.environ[e]:
                os.environ[e] = os.environ[e].replace(builddir + "/", newbuilddir + "/")
            if os.environ[e].endswith(builddir):
                os.environ[e] = os.environ[e].replace(builddir, newbuilddir)

        subprocess.check_output("git init; git add *; git commit -a -m 'initial'", cwd=newselftestdir, shell=True)

        # Tried to used bitbake-layers add/remove but it requires recipe parsing and hence is too slow
        subprocess.check_output("sed %s/conf/bblayers.conf -i -e 's#%s#%s#g'" % (newbuilddir, selftestdir, newselftestdir), cwd=newbuilddir, shell=True)

        os.chdir(newbuilddir)

        def patch_test(t):
            if not hasattr(t, "tc"):
                return
            cp = t.tc.config_paths
            for p in cp:
                if selftestdir in cp[p] and newselftestdir not in cp[p]:
                    cp[p] = cp[p].replace(selftestdir, newselftestdir)
                if builddir in cp[p] and newbuilddir not in cp[p]:
                    cp[p] = cp[p].replace(builddir, newbuilddir)

        def patch_suite(s):
            for x in s:
                if isinstance(x, unittest.TestSuite):
                    patch_suite(x)
                else:
                    patch_test(x)

        patch_suite(suite)

        return (builddir, newbuilddir)

    def prepareSuite(self, suites, processes):
        if processes:
            from oeqa.core.utils.concurrencytest import ConcurrentTestSuite

            return ConcurrentTestSuite(suites, processes, self.setup_builddir, self.removebuilddir)
        else:
            return NonConcurrentTestSuite(suites, processes, self.setup_builddir, self.removebuilddir)

    def runTests(self, processes=None, machine=None, skips=[]):
        if machine:
            self.custommachine = machine
            if machine == 'random':
                self.custommachine = choice(self.machines)
            self.logger.info('Run tests with custom MACHINE set to: %s' % \
                    self.custommachine)
        return super(OESelftestTestContext, self).runTests(processes, skips)

    def listTests(self, display_type, machine=None):
        return super(OESelftestTestContext, self).listTests(display_type)

class OESelftestTestContextExecutor(OETestContextExecutor):
    _context_class = OESelftestTestContext
    _script_executor = 'oe-selftest'

    name = 'oe-selftest'
    help = 'oe-selftest test component'
    description = 'Executes selftest tests'

    def register_commands(self, logger, parser):
        group = parser.add_mutually_exclusive_group(required=True)

        group.add_argument('-a', '--run-all-tests', default=False,
                action="store_true", dest="run_all_tests",
                help='Run all (unhidden) tests')
        group.add_argument('-r', '--run-tests', required=False, action='store',
                nargs='+', dest="run_tests", default=None,
                help='Select what tests to run (modules, classes or test methods). Format should be: <module>.<class>.<test_method>')

        group.add_argument('-m', '--list-modules', required=False,
                action="store_true", default=False,
                help='List all available test modules.')
        group.add_argument('--list-classes', required=False,
                action="store_true", default=False,
                help='List all available test classes.')
        group.add_argument('-l', '--list-tests', required=False,
                action="store_true", default=False,
                help='List all available tests.')

        parser.add_argument('-R', '--skip-tests', required=False, action='store',
                nargs='+', dest="skips", default=None,
                help='Skip the tests specified. Format should be <module>[.<class>[.<test_method>]]')
        parser.add_argument('-j', '--num-processes', dest='processes', action='store',
                type=int, help="number of processes to execute in parallel with")

        parser.add_argument('--machine', required=False, choices=['random', 'all'],
                            help='Run tests on different machines (random/all).')

        parser.add_argument('-t', '--select-tag', dest="select_tags",
                action='append', default=None,
                help='Filter all (unhidden) tests to any that match any of the specified tag(s).')
        parser.add_argument('-T', '--exclude-tag', dest="exclude_tags",
                action='append', default=None,
                help='Exclude all (unhidden) tests that match any of the specified tag(s). (exclude applies before select)')

        parser.add_argument('-K', '--keep-builddir', action='store_true',
                help='Keep the test build directory even if all tests pass')

        parser.add_argument('-B', '--newbuilddir', help='New build directory to use for tests.')
        parser.add_argument('-v', '--verbose', action='store_true')
        parser.set_defaults(func=self.run)

    def _get_available_machines(self):
        machines = []

        bbpath = self.tc_kwargs['init']['td']['BBPATH'].split(':')
    
        for path in bbpath:
            found_machines = glob.glob(os.path.join(path, 'conf', 'machine', '*.conf'))
            if found_machines:
                for i in found_machines:
                    # eg: '/home/<user>/poky/meta-intel/conf/machine/intel-core2-32.conf'
                    machines.append(os.path.splitext(os.path.basename(i))[0])
    
        return machines

    def _get_cases_paths(self, bbpath):
        cases_paths = []
        for layer in bbpath:
            cases_dir = os.path.join(layer, 'lib', 'oeqa', 'selftest', 'cases')
            if os.path.isdir(cases_dir):
                cases_paths.append(cases_dir)
        return cases_paths

    def _process_args(self, logger, args):
        args.test_start_time = time.strftime("%Y%m%d%H%M%S")
        args.test_data_file = None
        args.CASES_PATHS = None

        bbvars = get_bb_vars()
        logdir = os.environ.get("BUILDDIR")
        if 'LOG_DIR' in bbvars:
            logdir = bbvars['LOG_DIR']
        bb.utils.mkdirhier(logdir)
        args.output_log = logdir + '/%s-results-%s.log' % (self.name, args.test_start_time)

        super(OESelftestTestContextExecutor, self)._process_args(logger, args)

        if args.list_modules:
            args.list_tests = 'module'
        elif args.list_classes:
            args.list_tests = 'class'
        elif args.list_tests:
            args.list_tests = 'name'

        self.tc_kwargs['init']['td'] = bbvars
        self.tc_kwargs['init']['machines'] = self._get_available_machines()

        builddir = os.environ.get("BUILDDIR")
        self.tc_kwargs['init']['config_paths'] = {}
        self.tc_kwargs['init']['config_paths']['testlayer_path'] = get_test_layer()
        self.tc_kwargs['init']['config_paths']['builddir'] = builddir
        self.tc_kwargs['init']['config_paths']['localconf'] = os.path.join(builddir, "conf/local.conf")
        self.tc_kwargs['init']['config_paths']['bblayers'] = os.path.join(builddir, "conf/bblayers.conf")
        self.tc_kwargs['init']['newbuilddir'] = args.newbuilddir
        self.tc_kwargs['init']['keep_builddir'] = args.keep_builddir

        def tag_filter(tags):
            if args.exclude_tags:
                if any(tag in args.exclude_tags for tag in tags):
                    return True
            if args.select_tags:
                if not tags or not any(tag in args.select_tags for tag in tags):
                    return True
            return False

        if args.select_tags or args.exclude_tags:
            self.tc_kwargs['load']['tags_filter'] = tag_filter

        self.tc_kwargs['run']['skips'] = args.skips
        self.tc_kwargs['run']['processes'] = args.processes

    def _pre_run(self):
        def _check_required_env_variables(vars):
            for var in vars:
                if not os.environ.get(var):
                    self.tc.logger.error("%s is not set. Did you forget to source your build environment setup script?" % var)
                    raise OEQAPreRun

        def _check_presence_meta_selftest():
            builddir = os.environ.get("BUILDDIR")
            if os.getcwd() != builddir:
                self.tc.logger.info("Changing cwd to %s" % builddir)
                os.chdir(builddir)

            if not "meta-selftest" in self.tc.td["BBLAYERS"]:
                self.tc.logger.warning("meta-selftest layer not found in BBLAYERS, adding it")
                meta_selftestdir = os.path.join(
                    self.tc.td["BBLAYERS_FETCH_DIR"], 'meta-selftest')
                if os.path.isdir(meta_selftestdir):
                    runCmd("bitbake-layers add-layer %s" %meta_selftestdir)
                    # reload data is needed because a meta-selftest layer was add
                    self.tc.td = get_bb_vars()
                    self.tc.config_paths['testlayer_path'] = get_test_layer()
                else:
                    self.tc.logger.error("could not locate meta-selftest in:\n%s" % meta_selftestdir)
                    raise OEQAPreRun

        def _add_layer_libs():
            bbpath = self.tc.td['BBPATH'].split(':')
            layer_libdirs = [p for p in (os.path.join(l, 'lib') \
                    for l in bbpath) if os.path.exists(p)]
            if layer_libdirs:
                self.tc.logger.info("Adding layer libraries:")
                for l in layer_libdirs:
                    self.tc.logger.info("\t%s" % l)

                sys.path.extend(layer_libdirs)
                importlib.reload(oeqa.selftest)

        _check_required_env_variables(["BUILDDIR"])
        _check_presence_meta_selftest()

        if "buildhistory.bbclass" in self.tc.td["BBINCLUDED"]:
            self.tc.logger.error("You have buildhistory enabled already and this isn't recommended for selftest, please disable it first.")
            raise OEQAPreRun

        if "rm_work.bbclass" in self.tc.td["BBINCLUDED"]:
            self.tc.logger.error("You have rm_work enabled which isn't recommended while running oe-selftest. Please disable it before continuing.")
            raise OEQAPreRun

        if "PRSERV_HOST" in self.tc.td:
            self.tc.logger.error("Please unset PRSERV_HOST in order to run oe-selftest")
            raise OEQAPreRun

        if "SANITY_TESTED_DISTROS" in self.tc.td:
            self.tc.logger.error("Please unset SANITY_TESTED_DISTROS in order to run oe-selftest")
            raise OEQAPreRun

        _add_layer_libs()

        self.tc.logger.info("Running bitbake -e to test the configuration is valid/parsable")
        runCmd("bitbake -e")

    def get_json_result_dir(self, args):
        json_result_dir = os.path.join(self.tc.td["LOG_DIR"], 'oeqa')
        if "OEQA_JSON_RESULT_DIR" in self.tc.td:
            json_result_dir = self.tc.td["OEQA_JSON_RESULT_DIR"]

        return json_result_dir

    def get_configuration(self, args):
        import platform
        from oeqa.utils.metadata import metadata_from_bb
        metadata = metadata_from_bb()
        configuration = {'TEST_TYPE': 'oeselftest',
                        'STARTTIME': args.test_start_time,
                        'MACHINE': self.tc.td["MACHINE"],
                        'HOST_DISTRO': oe.lsb.distro_identifier().replace(' ', '-'),
                        'HOST_NAME': metadata['hostname'],
                        'LAYERS': metadata['layers']}
        return configuration

    def get_result_id(self, configuration):
        return '%s_%s_%s_%s' % (configuration['TEST_TYPE'], configuration['HOST_DISTRO'], configuration['MACHINE'], configuration['STARTTIME'])

    def _internal_run(self, logger, args):
        self.module_paths = self._get_cases_paths(
                self.tc_kwargs['init']['td']['BBPATH'].split(':'))

        self.tc = self._context_class(**self.tc_kwargs['init'])
        try:
            self.tc.loadTests(self.module_paths, **self.tc_kwargs['load'])
        except OEQATestNotFound as ex:
            logger.error(ex)
            sys.exit(1)

        if args.list_tests:
            rc = self.tc.listTests(args.list_tests, **self.tc_kwargs['list'])
        else:
            self._pre_run()
            rc = self.tc.runTests(**self.tc_kwargs['run'])
            configuration = self.get_configuration(args)
            rc.logDetails(self.get_json_result_dir(args),
                          configuration,
                          self.get_result_id(configuration))
            rc.logSummary(self.name)

        return rc

    def run(self, logger, args):
        self._process_args(logger, args)

        rc = None
        try:
            if args.machine:
                logger.info('Custom machine mode enabled. MACHINE set to %s' %
                        args.machine)

                if args.machine == 'all':
                    results = []
                    for m in self.tc_kwargs['init']['machines']:
                        self.tc_kwargs['run']['machine'] = m
                        results.append(self._internal_run(logger, args))

                        # XXX: the oe-selftest script only needs to know if one
                        # machine run fails
                        for r in results:
                            rc = r
                            if not r.wasSuccessful():
                                break

                else:
                    self.tc_kwargs['run']['machine'] = args.machine
                    return self._internal_run(logger, args)

            else:
                self.tc_kwargs['run']['machine'] = args.machine
                rc = self._internal_run(logger, args)
        finally:
            config_paths = self.tc_kwargs['init']['config_paths']

            output_link = os.path.join(os.path.dirname(args.output_log),
                    "%s-results.log" % self.name)
            if os.path.lexists(output_link):
                os.remove(output_link)
            os.symlink(args.output_log, output_link)

        return rc

_executor_class = OESelftestTestContextExecutor
