# Lint as: python2, python3
# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""This module provides cras DBus audio utilities."""

import logging
import multiprocessing
import pprint

from autotest_lib.client.cros.audio import cras_utils


def _set_default_main_loop():
    """Sets the gobject main loop to be the event loop for DBus.

    @raises: ImportError if dbus.mainloop.glib can not be imported.

    """
    try:
        import dbus.mainloop.glib
    except ImportError as e:
        logging.exception(
                'Can not import dbus.mainloop.glib: %s. '
                'This method should only be called on Cros device.', e)
        raise
    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)


def _get_gobject():
    """Tries to import gobject.

    @returns: The imported gobject module.

    @raises: ImportError if gobject can not be imported.

    """
    try:
        import gobject
    except ImportError as e:
        logging.exception(
                'Can not import gobject: %s. This method should only be '
                'called on Cros device.', e)
        raise
    return gobject


class CrasDBusMonitorError(Exception):
    """Error in CrasDBusMonitor."""
    pass


class CrasDBusMonitor(object):
    """Monitor for DBus signal from Cras."""
    def __init__(self):
        _set_default_main_loop()
        # Acquires a new Cras interface through a new dbus.SystemBus instance
        # which has default main loop.
        self._iface = cras_utils.get_cras_control_interface(private=True)
        self._loop = _get_gobject().MainLoop()
        self._count = 0


class CrasDBusSignalListener(CrasDBusMonitor):
    """Listener for certain signal."""
    def __init__(self):
        super(CrasDBusSignalListener, self).__init__()
        self._target_signal_count = 0


    def wait_for_nodes_changed(self, target_signal_count, timeout_secs):
        """Waits for NodesChanged signal.

        @param target_signal_count: The expected number of signal.
        @param timeout_secs: The timeout in seconds.

        @raises: CrasDBusMonitorError if there is no enough signals before
                 timeout.

        """
        self._target_signal_count = target_signal_count
        signal_match = self._iface.connect_to_signal(
                'NodesChanged', self._nodes_changed_handler)
        _get_gobject().timeout_add(
                timeout_secs * 1000, self._timeout_quit_main_loop)

        # Blocks here until _nodes_changed_handler or _timeout_quit_main_loop
        # quits the loop.
        self._loop.run()

        signal_match.remove()
        if self._count < self._target_signal_count:
            raise CrasDBusMonitorError('Timeout')


    def _nodes_changed_handler(self):
        """Handler for NodesChanged signal."""
        if self._loop.is_running():
            logging.debug('Got NodesChanged signal when loop is running.')
            self._count = self._count + 1
            logging.debug('count = %d', self._count)
            if self._count >= self._target_signal_count:
                logging.debug('Quit main loop')
                self._loop.quit()
        else:
            logging.debug('Got NodesChanged signal when loop is not running.'
                          ' Ignore it')


    def _timeout_quit_main_loop(self):
        """Handler for timeout in main loop.

        @returns: False so this callback will not be called again.

        """
        if self._loop.is_running():
            logging.error('Quit main loop because of timeout')
            self._loop.quit()
        else:
            logging.debug(
                    'Got _quit_main_loop after main loop quits. Ignore it')

        return False


class CrasDBusBackgroundSignalCounter(object):
    """Controls signal counter which runs in background."""
    def __init__(self):
        self._proc = None
        self._signal_name = None
        self._counter = None
        self._parent_conn = None
        self._child_conn = None


    def start(self, signal_name):
        """Starts the signal counter in a subprocess.

        @param signal_name: The name of the signal to count.

        """
        self._signal_name = signal_name
        self._parent_conn, self._child_conn = multiprocessing.Pipe()
        self._proc = multiprocessing.Process(
                target=self._run, args=(self._child_conn,))
        self._proc.daemon = True
        self._proc.start()


    def _run(self, child_conn):
        """Runs CrasDBusCounter.

        This should be called in a subprocess.
        This blocks until parent_conn send stop command to the pipe.

        """
        self._counter = CrasDBusCounter(self._signal_name, child_conn)
        self._counter.run()


    def stop(self):
        """Stops the CrasDBusCounter by sending stop command to parent_conn.

        The result of CrasDBusCounter in its subproces can be obtained by
        reading from parent_conn.

        @returns: The count of the signal of interest.

        """
        self._parent_conn.send(CrasDBusCounter.STOP_CMD)
        return self._parent_conn.recv()


class CrasDBusCounter(CrasDBusMonitor):
    """Counter for DBus signal sent from Cras"""

    _CHECK_QUIT_PERIOD_SECS = 0.1
    STOP_CMD = 'stop'

    def __init__(self, signal_name, child_conn, ignore_redundant=True):
        """Initializes a CrasDBusCounter.

        @param signal_name: The name of the signal of interest.
        @param child_conn: A multiprocessing.Pipe which is used to receive stop
                     signal and to send the counting result.
        @param ignore_redundant: Ignores signal if GetNodes result stays the
                     same. This happens when there is change in unplugged nodes,
                     which does not affect Cras client.

        """
        super(CrasDBusCounter, self).__init__()
        self._signal_name = signal_name
        self._count = None
        self._child_conn = child_conn
        self._ignore_redundant = ignore_redundant
        self._nodes = None


    def run(self):
        """Runs the gobject main loop and listens for the signal."""
        self._count = 0

        self._nodes = cras_utils.get_cras_nodes()
        logging.debug('Before starting the counter')
        logging.debug('nodes = %s', pprint.pformat(self._nodes))

        signal_match = self._iface.connect_to_signal(
                self._signal_name, self._signal_handler)
        _get_gobject().timeout_add(
                 int(self._CHECK_QUIT_PERIOD_SECS * 1000),
                 self._check_quit_main_loop)

        logging.debug('Start counting for signal %s', self._signal_name)

        # Blocks here until _check_quit_main_loop quits the loop.
        self._loop.run()

        signal_match.remove()

        logging.debug('Count result: %s', self._count)
        self._child_conn.send(self._count)


    def _signal_handler(self):
        """Handler for signal."""
        if self._loop.is_running():
            logging.debug('Got %s signal when loop is running.',
                          self._signal_name)

            logging.debug('Getting nodes.')
            nodes = cras_utils.get_cras_nodes()
            logging.debug('nodes = %s', pprint.pformat(nodes))
            if self._ignore_redundant and self._nodes == nodes:
                logging.debug('Nodes did not change. Ignore redundant signal')
                return

            self._count = self._count + 1
            logging.debug('count = %d', self._count)
        else:
            logging.debug('Got %s signal when loop is not running.'
                          ' Ignore it', self._signal_name)


    def _should_stop(self):
        """Checks if user wants to stop main loop."""
        if self._child_conn.poll():
            if self._child_conn.recv() == self.STOP_CMD:
                logging.debug('Should stop')
                return True
        return False


    def _check_quit_main_loop(self):
        """Handler for timeout in main loop.

        @returns: True so this callback will not be called again.
                  False if user quits main loop.

        """
        if self._loop.is_running():
            logging.debug('main loop is running in _check_quit_main_loop')
            if self._should_stop():
                logging.debug('Quit main loop because of stop command')
                self._loop.quit()
                return False
            else:
                logging.debug('No stop command, keep running')
                return True
        else:
            logging.debug(
                    'Got _quit_main_loop after main loop quits. Ignore it')

            return False


class CrasDBusMonitorUnexpectedNodesChanged(Exception):
    """Error for unexpected nodes changed."""
    pass


def wait_for_unexpected_nodes_changed(timeout_secs):
    """Waits for unexpected nodes changed signal in this blocking call.

    @param timeout_secs: Timeout in seconds for waiting.

    @raises CrasDBusMonitorUnexpectedNodesChanged if there is NodesChanged
            signal

    """
    try:
        CrasDBusSignalListener().wait_for_nodes_changed(1, timeout_secs)
    except CrasDBusMonitorError:
        logging.debug('There is no NodesChanged signal, as expected')
        return
    raise CrasDBusMonitorUnexpectedNodesChanged()
