# Copyright 2020 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Implementation of the graphics_TraceReplayExtended server test."""

import logging
import os
import threading
import time

from autotest_lib.client.common_lib import error
from autotest_lib.server import test
from autotest_lib.server.cros.graphics import graphics_power
from autotest_lib.server.site_tests.tast import tast


class TastManagerThread(threading.Thread):
    """Thread for running a local tast test from an autotest server test."""

    def __init__(self,
                 host,
                 tast_instance,
                 client_test,
                 max_duration_minutes,
                 build_bundle,
                 varslist=None,
                 command_args=None):
        """Initializes the thread.

        Args:
            host: An autotest host instance.
            tast_instance: An instance of the tast.tast() class.
            client_test: String identifying which tast test to run.
            max_duration_minutes: Float defining the maximum running time of the
                managed sub-test.
            build_bundle: String defining which tast test bundle to build and
                query for the client_test.
            varslist: list of strings that define dynamic variables made
                available to tast tests at runtime via `tast run -var=name=value
                ...`. Each string should be formatted as 'name=value'.
            command_args: list of strings that are passed as args to the `tast
                run` command.
        """
        super(TastManagerThread, self).__init__(name=__name__)
        self.tast = tast_instance
        self.tast.initialize(
            host=host,
            test_exprs=[client_test],
            ignore_test_failures=True,
            max_run_sec=max_duration_minutes * 60,
            command_args=command_args if command_args else [],
            build_bundle=build_bundle,
            varslist=varslist)

    def run(self):
        logging.info('Started thread: %s', self.__class__.__name__)
        self.tast.run_once()


class graphics_TraceReplayExtended(test.test):
    """Autotest server test for running repeated trace replays.

    This test simultaneously initiates system performance logging and extended
    trace replay processes on a target host, and parses their test results for
    combined analysis and reporting.
    """
    version = 1

    @staticmethod
    def _initialize_dir_on_host(host, directory):
        """Initialize a directory to a consistent (empty) state on the host.

        Args:
            host: An autotest host instance.
            directory: String defining the location of the directory to
                initialize.

        Raises:
            TestFail: If the directory cannot be initialized.
        """
        try:
            host.run('rm -r %(0)s 2>/dev/null || true; ! test -d %(0)s' %
                     {'0': directory})
            host.run('mkdir -p %s' % directory)
        except (error.AutotestHostRunCmdError, error.AutoservRunError) as err:
            logging.exception(err)
            raise error.TestFail(
                'Failed to initialize directory "%s" on the test host' %
                directory)

    @staticmethod
    def _cleanup_dir_on_host(host, directory):
        """Ensure that a directory and its contents are deleted on the host.

        Args:
            host: An autotest host instance.
            directory: String defining the location of the directory to delete.

        Raises:
            TestFail: If the directory remains on the host.
        """
        try:
            host.run('rm -r %(0)s || true; ! test -d %(0)s' % {'0': directory})
        except (error.AutotestHostRunCmdError, error.AutoservRunError) as err:
            logging.exception(err)
            raise error.TestFail(
                'Failed to cleanup directory "%s" on the test host' % directory)

    def run_once(self,
                 host,
                 client_tast_test,
                 max_duration_minutes,
                 tast_build_bundle='cros',
                 tast_varslist=None,
                 tast_command_args=None):
        """Runs the test.

        Args:
            host: An autotest host instance.
            client_tast_test: String defining which tast test to run.
            max_duration_minutes: Float defining the maximum running time of the
                managed sub-test.
            tast_build_bundle: String defining which tast test bundle to build
                and query for the client_test.
            tast_varslist: list of strings that define dynamic variables made
                available to tast tests at runtime via `tast run -var=name=value
                ...`. Each string should be formatted as 'name=value'.
            tast_command_args: list of strings that are passed as args to the
                `tast run` command.
        """
        # Construct a suffix tag indicating which managing test is using logged
        # data from the graphics_Power subtest.
        trace_name = client_tast_test.split('.')[-1]

        # Define paths of signal files for basic RPC/IPC between sub-tests.
        temp_io_root = '/tmp/%s/' % self.__class__.__name__
        result_dir = os.path.join(temp_io_root, 'results')
        signal_running_file = os.path.join(temp_io_root, 'signal_running')
        signal_checkpoint_file = os.path.join(temp_io_root, 'signal_checkpoint')

        # This test is responsible for creating/deleting root and resultdir.
        logging.debug('Creating temporary IPC/RPC dir: %s', temp_io_root)
        self._initialize_dir_on_host(host, temp_io_root)
        self._initialize_dir_on_host(host, result_dir)

        # Start background system performance monitoring process on the test
        # target (via an autotest client 'power_Test').
        logging.debug('Connecting to autotest client on host')
        graphics_power_thread = graphics_power.GraphicsPowerThread(
            host=host,
            max_duration_minutes=max_duration_minutes,
            test_tag='Trace' + '.' + trace_name,
            pdash_note='',
            result_dir=result_dir,
            signal_running_file=signal_running_file,
            signal_checkpoint_file=signal_checkpoint_file)
        graphics_power_thread.start()

        logging.info('Waiting for graphics_Power subtest to initialize...')
        try:
            graphics_power_thread.wait_until_running(timeout=120)
        except Exception as err:
            logging.exception(err)
            raise error.TestFail(
                'An error occured during graphics_Power subtest initialization')
        logging.info('The graphics_Power subtest was properly initialized')

        # Start repeated trace replay process on the test target (via a tast
        # local test).
        logging.info('Running Tast test: %s', client_tast_test)
        tast_outputdir = os.path.join(self.outputdir, 'tast')
        if not os.path.exists(tast_outputdir):
            logging.debug('Creating tast outputdir: %s', tast_outputdir)
            os.makedirs(tast_outputdir)

        if not tast_varslist:
            tast_varslist = []
        tast_varslist.extend([
            'graphics.TraceReplayExtended.resultDir=' + result_dir,
            'graphics.TraceReplayExtended.signalRunningFile=' +
            signal_running_file,
            'graphics.TraceReplayExtended.signalCheckpointFile=' +
            signal_checkpoint_file,
        ])

        tast_instance = tast.tast(
            job=self.job, bindir=self.bindir, outputdir=tast_outputdir)
        tast_manager_thread = TastManagerThread(
            host,
            tast_instance,
            client_tast_test,
            max_duration_minutes,
            tast_build_bundle,
            varslist=tast_varslist,
            command_args=tast_command_args)
        tast_manager_thread.start()

        # Block until both subtests finish.
        threads = [graphics_power_thread, tast_manager_thread]
        stop_attempts = 0
        while threads:
            # TODO(ryanneph): Move stop signal emission to tast test instance.
            if (not tast_manager_thread.is_alive() and
                    graphics_power_thread.is_alive() and stop_attempts < 1):
                logging.info('Attempting to stop graphics_Power thread')
                graphics_power_thread.stop(timeout=0)
                stop_attempts += 1

            # Raise test failure if graphics_Power thread ends before tast test.
            if (not graphics_power_thread.is_alive() and
                    tast_manager_thread.is_alive()):
                raise error.TestFail(
                    'The graphics_Power subtest ended too soon.')

            for thread in list(threads):
                if not thread.is_alive():
                    logging.info('Thread "%s" has ended',
                                 thread.__class__.__name__)
                    threads.remove(thread)
            time.sleep(1)

        client_result_dir = os.path.join(self.outputdir, 'client_results')
        logging.info('Saving client results to %s', client_result_dir)
        host.get_file(result_dir, client_result_dir)

        # Ensure the host filesystem is clean for the next test.
        self._cleanup_dir_on_host(host, result_dir)
        self._cleanup_dir_on_host(host, temp_io_root)

        # TODO(ryanneph): Implement results parsing/analysis/reporting
