"""
This module contains the actions that a configurable CFM test can execute.
"""
import abc
import logging
import random
import re
import sys
import time

class Action(object):
    """
    Abstract base class for all actions.
    """
    __metaclass__ = abc.ABCMeta

    def __repr__(self):
        return self.__class__.__name__

    def execute(self, context):
        """
        Executes the action.

        @param context ActionContext instance providing dependencies to the
                action.
        """
        logging.info('Executing action "%s"', self)
        self.do_execute(context)
        logging.info('Done executing action "%s"', self)

    @abc.abstractmethod
    def do_execute(self, context):
        """
        Performs the actual execution.

        Subclasses must override this method.

        @param context ActionContext instance providing dependencies to the
                action.
        """
        pass

class MuteMicrophone(Action):
    """
    Mutes the microphone in a call.
    """
    def do_execute(self, context):
        context.cfm_facade.mute_mic()

class UnmuteMicrophone(Action):
    """
    Unmutes the microphone in a call.
    """
    def do_execute(self, context):
        context.cfm_facade.unmute_mic()

class WaitForMeetingsLandingPage(Action):
    """
  Wait for landing page to load after reboot.
  """

    def do_execute(self, context):
        context.cfm_facade.wait_for_meetings_landing_page()


class JoinMeeting(Action):
    """
    Joins a meeting.
    """
    def __init__(self, meeting_code):
        """
        Initializes.

        @param meeting_code The meeting code for the meeting to join.
        """
        super(JoinMeeting, self).__init__()
        self.meeting_code = meeting_code

    def __repr__(self):
        return 'JoinMeeting "%s"' % self.meeting_code

    def do_execute(self, context):
        context.cfm_facade.join_meeting_session(self.meeting_code)

class CreateMeeting(Action):
    """
    Creates a new meeting from the landing page.
    """
    def do_execute(self, context):
        context.cfm_facade.start_meeting_session()

class LeaveMeeting(Action):
    """
    Leaves the current meeting.
    """
    def do_execute(self, context):
        context.cfm_facade.end_meeting_session()

class RebootDut(Action):
    """
    Reboots the DUT.
    """
    def __init__(self, restart_chrome_for_cfm=False):
        """Initializes.

        To enable the cfm_facade to interact with the CFM, Chrome needs an extra
        restart. Setting restart_chrome_for_cfm toggles this extra restart.

        @param restart_chrome_for_cfm If True, restarts chrome to enable
                the cfm_facade and waits for the telemetry commands to become
                available. If false, does not do an extra restart of Chrome.
        """
        self._restart_chrome_for_cfm = restart_chrome_for_cfm

    def do_execute(self, context):
        context.host.reboot()
        if self._restart_chrome_for_cfm:
            context.cfm_facade.restart_chrome_for_cfm()
            context.cfm_facade.wait_for_telemetry_commands()

class RepeatTimes(Action):
    """
    Repeats a scenario a number of times.
    """
    def __init__(self, times, scenario):
        """
        Initializes.

        @param times The number of times to repeat the scenario.
        @param scenario The scenario to repeat.
        """
        super(RepeatTimes, self).__init__()
        self.times = times
        self.scenario = scenario

    def __str__(self):
        return 'Repeat[scenario=%s, times=%s]' % (self.scenario, self.times)

    def do_execute(self, context):
        for _ in range(self.times):
            self.scenario.execute(context)

class AssertFileDoesNotContain(Action):
    """
    Asserts that a file on the DUT does not contain specified regexes.
    """
    def __init__(self, path, forbidden_regex_list):
        """
        Initializes.

        @param path The file path on the DUT to check.
        @param forbidden_regex_list a list with regular expressions that should
                not appear in the file.
        """
        super(AssertFileDoesNotContain, self).__init__()
        self.path = path
        self.forbidden_regex_list = forbidden_regex_list

    def __repr__(self):
        return ('AssertFileDoesNotContain[path=%s, forbidden_regex_list=%s'
                % (self.path, self.forbidden_regex_list))

    def do_execute(self, context):
        contents = context.file_contents_collector.collect_file_contents(
                self.path)
        for forbidden_regex in self.forbidden_regex_list:
            match = re.search(forbidden_regex, contents)
            if match:
                raise AssertionError(
                        'Regex "%s" matched "%s" in "%s"'
                        % (forbidden_regex, match.group(), self.path))

class AssertUsbDevices(Action):
    """
    Asserts that USB devices with given specs matches a predicate.
    """
    def __init__(
            self,
            usb_device_specs,
            predicate=lambda usb_device_list: len(usb_device_list) == 1):
        """
        Initializes with a spec to assert and a predicate.

        @param usb_device_specs a list of UsbDeviceSpecs for the devices to
                check.
        @param predicate A function that accepts a list of UsbDevices
                and returns true if the list is as expected or false otherwise.
                If the method returns false an AssertionError is thrown.
                The default predicate checks that there is exactly one item
                in the list.
        """
        super(AssertUsbDevices, self).__init__()
        self._usb_device_specs = usb_device_specs
        self._predicate = predicate

    def do_execute(self, context):
        usb_devices = context.usb_device_collector.get_devices_by_spec(
                *self._usb_device_specs)
        if not self._predicate(usb_devices):
            raise AssertionError(
                    'Assertion failed for usb device specs %s. '
                    'Usb devices were: %s'
                    % (self._usb_device_specs, usb_devices))

    def __str__(self):
        return 'AssertUsbDevices for specs %s' % str(self._usb_device_specs)

class SelectScenarioAtRandom(Action):
    """
    Executes a randomly selected scenario a number of times.

    Note that there is no validation performed - you have to take care
    so that it makes sense to execute the supplied scenarios in any order
    any number of times.
    """
    def __init__(
            self,
            scenarios,
            run_times,
            random_seed=random.randint(0, sys.maxsize)):
        """
        Initializes.

        @param scenarios An iterable with scenarios to choose from.
        @param run_times The number of scenarios to run. I.e. the number of
            times a random scenario is selected.
        @param random_seed The seed to use for the random generator. Providing
            the same seed as an earlier run will execute the scenarios in the
            same order. Optional, by default a random seed is used.
        """
        super(SelectScenarioAtRandom, self).__init__()
        self._scenarios = scenarios
        self._run_times = run_times
        self._random_seed = random_seed
        self._random = random.Random(random_seed)

    def do_execute(self, context):
        for _ in range(self._run_times):
            self._random.choice(self._scenarios).execute(context)

    def __repr__(self):
        return ('SelectScenarioAtRandom [seed=%s, run_times=%s, scenarios=%s]'
                % (self._random_seed, self._run_times, self._scenarios))


class PowerCycleUsbPort(Action):
    """
    Power cycle USB ports that a specific peripheral type is attached to.
    """
    def __init__(
            self,
            usb_device_specs,
            wait_for_change_timeout=10,
            filter_function=lambda x: x):
        """
        Initializes.

        @param usb_device_specs List of UsbDeviceSpecs of the devices to power
            cycle the port for.
        @param wait_for_change_timeout The timeout in seconds for waiting
            for devices to disappeard/appear after turning power off/on.
            If the devices do not disappear/appear within the timeout an
            error is raised.
        @param filter_function Function accepting a list of UsbDevices and
            returning a list of UsbDevices that should be power cycled. The
            default is to return the original list, i.e. power cycle all
            devices matching the usb_device_specs.

        @raises TimeoutError if the devices do not turn off/on within
            wait_for_change_timeout seconds.
        """
        self._usb_device_specs = usb_device_specs
        self._filter_function = filter_function
        self._wait_for_change_timeout = wait_for_change_timeout

    def do_execute(self, context):
        def _get_devices():
            return context.usb_device_collector.get_devices_by_spec(
                    *self._usb_device_specs)
        devices = _get_devices()
        devices_to_cycle = self._filter_function(devices)
        # If we are asked to power cycle a device connected to a USB hub (for
        # example a Mimo which has an internal hub) the devices's bus and port
        # cannot be used. Those values represent the bus and port of the hub.
        # Instead we must locate the device that is actually connected to the
        # physical USB port. This device is the parent at level 1 of the current
        # device. If the device is not connected to a hub, device.get_parent(1)
        # will return the device itself.
        devices_to_cycle = [device.get_parent(1) for device in devices_to_cycle]
        logging.debug('Power cycling devices: %s', devices_to_cycle)
        port_ids = [(d.bus, d.port) for d in devices_to_cycle]
        context.usb_port_manager.set_port_power(port_ids, False)
        # TODO(kerl): We should do a better check than counting devices.
        # Possibly implementing __eq__() in UsbDevice and doing a proper
        # intersection to see which devices are running or not.
        expected_devices_after_power_off = len(devices) - len(devices_to_cycle)
        _wait_for_condition(
                lambda: len(_get_devices()) == expected_devices_after_power_off,
                self._wait_for_change_timeout)
        context.usb_port_manager.set_port_power(port_ids, True)
        _wait_for_condition(
                lambda: len(_get_devices()) == len(devices),
                self._wait_for_change_timeout)

    def __repr__(self):
        return ('PowerCycleUsbPort[usb_device_specs=%s, '
                'wait_for_change_timeout=%s]'
                % (str(self._usb_device_specs), self._wait_for_change_timeout))


class Sleep(Action):
    """
    Action that sleeps for a number of seconds.
    """
    def __init__(self, num_seconds):
        """
        Initializes.

        @param num_seconds The number of seconds to sleep.
        """
        self._num_seconds = num_seconds

    def do_execute(self, context):
        time.sleep(self._num_seconds)

    def __repr__(self):
        return 'Sleep[num_seconds=%s]' % self._num_seconds


class RetryAssertAction(Action):
    """
    Action that retries an assertion action a number of times if it fails.

    An example use case for this action is to verify that a peripheral device
    appears after power cycling. E.g.:
        PowerCycleUsbPort(ATRUS),
        RetryAssertAction(AssertUsbDevices(ATRUS), 10)
    """
    def __init__(self, action, num_tries, retry_delay_seconds=1):
        """
        Initializes.

        @param action The action to execute.
        @param num_tries The number of times to try the action before failing
            for real. Must be more than 0.
        @param retry_delay_seconds The number of seconds to sleep between
            retries.

        @raises ValueError if num_tries is below 1.
        """
        super(RetryAssertAction, self).__init__()
        if num_tries < 1:
            raise ValueError('num_tries must be > 0. Was %s' % num_tries)
        self._action = action
        self._num_tries = num_tries
        self._retry_delay_seconds = retry_delay_seconds

    def do_execute(self, context):
        for attempt in range(self._num_tries):
            try:
                self._action.execute(context)
                return
            except AssertionError as e:
                if attempt == self._num_tries - 1:
                    raise e
                else:
                    logging.info(
                            'Action %s failed, will retry %d more times',
                             self._action,
                             self._num_tries - attempt - 1,
                             exc_info=True)
                    time.sleep(self._retry_delay_seconds)

    def __repr__(self):
        return ('RetryAssertAction[action=%s, '
                'num_tries=%s, retry_delay_seconds=%s]'
                % (self._action, self._num_tries, self._retry_delay_seconds))


class AssertNoNewCrashes(Action):
    """
    Asserts that no new crash files exist on disk.
    """
    def do_execute(self, context):
        new_crash_files = context.crash_detector.get_new_crash_files()
        if new_crash_files:
            raise AssertionError(
                    'New crash files detected: %s' % str(new_crash_files))


class TimeoutError(RuntimeError):
    """
    Error raised when an operation times out.
    """
    pass


def _wait_for_condition(condition, timeout_seconds=10):
    """
    Wait for a condition to become true.

    Checks the condition every second.

    @param condition The condition to check - a function returning a boolean.
    @param timeout_seconds The timeout in seconds.

    @raises TimeoutError in case the condition does not become true within
        the timeout.
    """
    if condition():
        return
    for _ in range(timeout_seconds):
        time.sleep(1)
        if condition():
            return
    raise TimeoutError('Timeout after %s seconds waiting for condition %s'
                       % (timeout_seconds, condition))


class StartPerfMetricsCollection(Action):
    """
    Starts collecting performance data.

    Collection is performed in a background thread so this operation returns
    immediately.

    This action only collects the data, it does not upload it.
    Use UploadPerfMetrics to upload the data to the perf dashboard.
    """
    def do_execute(self, context):
        context.perf_metrics_collector.start()


class StopPerfMetricsCollection(Action):
    """
    Stops collecting performance data.

    This action only stops collecting the data, it does not upload it.
    Use UploadPerfMetrics to upload the data to the perf dashboard.
    """
    def do_execute(self, context):
        context.perf_metrics_collector.stop()


class UploadPerfMetrics(Action):
    """
    Uploads the collected perf metrics to the perf dashboard.
    """
    def do_execute(self, context):
        context.perf_metrics_collector.upload_metrics()


class CreateMeetingWithBots(Action):
    """
    Creates a new meeting prepopulated with bots.

    Call JoinMeetingWithBots() do join it with a CfM.
    """
    def __init__(self, bot_count, bots_ttl_min, muted=True):
        """
        Initializes.

        @param bot_count Amount of bots to be in the meeting.
        @param bots_ttl_min TTL in minutes after which the bots leave.
        @param muted If the bots are audio muted or not.
        """
        super(CreateMeetingWithBots, self).__init__()
        self._bot_count = bot_count
        # Adds an extra 30 seconds buffer
        self._bots_ttl_sec = bots_ttl_min * 60 + 30
        self._muted = muted

    def __repr__(self):
        return (
            'CreateMeetingWithBots:\n'
            ' bot_count: %d\n'
            ' bots_ttl_sec: %d\n'
            ' muted: %s' % (self._bot_count, self._bots_ttl_sec, self._muted)
        )

    def do_execute(self, context):
        if context.bots_meeting_code:
            raise AssertionError(
                'A meeting with bots is already running. '
                'Repeated calls to CreateMeetingWithBots() are not supported.')
        context.bots_meeting_code = context.bond_api.CreateConference()
        context.bond_api.AddBotsRequest(
            context.bots_meeting_code,
            self._bot_count,
            self._bots_ttl_sec);
        mute_cmd = 'mute_audio' if self._muted else 'unmute_audio'
        context.bond_api.ExecuteScript('@all %s' % mute_cmd,
                                       context.bots_meeting_code)


class JoinMeetingWithBots(Action):
    """
    Joins an existing meeting started via CreateMeetingWithBots().
    """
    def do_execute(self, context):
        meeting_code = context.bots_meeting_code
        if not meeting_code:
            raise AssertionError(
                'Meeting with bots was not started. '
                'Did you forget to call CreateMeetingWithBots()?')
        context.cfm_facade.join_meeting_session(context.bots_meeting_code)
