# Copyright 2018 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Module for the manager of services."""
# TODO(xpconanfan: move the device errors to a more generic location so
# other device controllers like iOS can share it.
import collections
import contextlib
import inspect

from mobly import expects
from mobly.controllers.android_device_lib import errors
from mobly.controllers.android_device_lib.services import base_service


class Error(errors.DeviceError):
    """Root error type for this module."""


class ServiceManager(object):
    """Manager for services of AndroidDevice.

    A service is a long running process that involves an Android device, like
    adb logcat or Snippet.
    """

    def __init__(self, device):
        self._service_objects = collections.OrderedDict()
        self._device = device

    def has_service_by_name(self, name):
        """Checks if the manager has a service registered with a specific name.

        Args:
            name: string, the name to look for.

        Returns:
            True if a service is registered with the specified name, False
            otherwise.
        """
        return name in self._service_objects

    @property
    def is_any_alive(self):
        """True if any service is alive; False otherwise."""
        for service in self._service_objects.values():
            if service.is_alive:
                return True
        return False

    def register(self, alias, service_class, configs=None, start_service=True):
        """Registers a service.

        This will create a service instance, starts the service, and adds the
        instance to the mananger.

        Args:
            alias: string, the alias for this instance.
            service_class: class, the service class to instantiate.
            configs: (optional) config object to pass to the service class's
                constructor.
            start_service: bool, whether to start the service instance or not.
                Default is True.
        """
        if not inspect.isclass(service_class):
            raise Error(self._device, '"%s" is not a class!' % service_class)
        if not issubclass(service_class, base_service.BaseService):
            raise Error(
                self._device,
                'Class %s is not a subclass of BaseService!' % service_class)
        if alias in self._service_objects:
            raise Error(
                self._device,
                'A service is already registered with alias "%s".' % alias)
        service_obj = service_class(self._device, configs)
        service_obj.alias = alias
        if start_service:
            service_obj.start()
        self._service_objects[alias] = service_obj

    def unregister(self, alias):
        """Unregisters a service instance.

        Stops a service and removes it from the manager.

        Args:
            alias: string, the alias of the service instance to unregister.
        """
        if alias not in self._service_objects:
            raise Error(self._device,
                        'No service is registered with alias "%s".' % alias)
        service_obj = self._service_objects.pop(alias)
        if service_obj.is_alive:
            with expects.expect_no_raises(
                    'Failed to stop service instance "%s".' % alias):
                service_obj.stop()

    def for_each(self, func):
        """Executes a function with all registered services.

        Args:
            func: function, the function to execute. This function should take
                a service object as args.
        """
        aliases = list(self._service_objects.keys())
        for alias in aliases:
            with expects.expect_no_raises(
                    'Failed to execute "%s" for service "%s".' %
                (func.__name__, alias)):
                func(self._service_objects[alias])

    def list_live_services(self):
        """Lists the aliases of all the services that are alive.

        Order of this list is determined by the order the services are
        registered in.

        Returns:
            list of strings, the aliases of the services that are running.
        """
        aliases = []
        self.for_each(lambda service: aliases.append(service.alias)
                      if service.is_alive else None)
        return aliases

    def create_output_excerpts_all(self, test_info):
        """Creates output excerpts from all services.

        This calls `create_output_excerpts` on all registered services.

        Args:
            test_info: RuntimeTestInfo, the test info associated with the scope
                of the excerpts.

        Returns:
            Dict, keys are the names of the services, values are the paths to
                the excerpt files created by the corresponding services.
        """
        excerpt_paths = {}

        def create_output_excerpts_for_one(service):
            if not service.is_alive:
                return
            paths = service.create_output_excerpts(test_info)
            excerpt_paths[service.alias] = paths

        self.for_each(create_output_excerpts_for_one)
        return excerpt_paths

    def unregister_all(self):
        """Safely unregisters all active instances.

        Errors occurred here will be recorded but not raised.
        """
        aliases = list(self._service_objects.keys())
        for alias in aliases:
            self.unregister(alias)

    def start_all(self):
        """Starts all inactive service instances.

        Services will be started in the order they were registered.
        """
        for alias, service in self._service_objects.items():
            if not service.is_alive:
                with expects.expect_no_raises('Failed to start service "%s".' %
                                              alias):
                    service.start()

    def start_services(self, service_alises):
        """Starts the specified services.

        Services will be started in the order specified by the input list.
        No-op for services that are already running.

        Args:
            service_alises: list of strings, the aliases of services to start.
        """
        for name in service_alises:
            if name not in self._service_objects:
                raise Error(
                    self._device,
                    'No service is registered under the name "%s", cannot start.'
                    % name)
            service = self._service_objects[name]
            if not service.is_alive:
                service.start()

    def stop_all(self):
        """Stops all active service instances.

        Services will be stopped in the reverse order they were registered.
        """
        # OrdereDict#items does not return a sequence in Python 3.4, so we have
        # to do a list conversion here.
        for alias, service in reversed(list(self._service_objects.items())):
            if service.is_alive:
                with expects.expect_no_raises('Failed to stop service "%s".' %
                                              alias):
                    service.stop()

    def pause_all(self):
        """Pauses all service instances.

        Services will be paused in the reverse order they were registered.
        """
        # OrdereDict#items does not return a sequence in Python 3.4, so we have
        # to do a list conversion here.
        for alias, service in reversed(list(self._service_objects.items())):
            with expects.expect_no_raises('Failed to pause service "%s".' %
                                          alias):
                service.pause()

    def resume_all(self):
        """Resumes all service instances.

        Services will be resumed in the order they were registered.
        """
        for alias, service in self._service_objects.items():
            with expects.expect_no_raises('Failed to resume service "%s".' %
                                          alias):
                service.resume()

    def resume_services(self, service_alises):
        """Resumes the specified services.

        Services will be resumed in the order specified by the input list.
        No-op for services that are already running.

        Args:
            service_alises: list of strings, the names of services to start.
        """
        for name in service_alises:
            if name not in self._service_objects:
                raise Error(
                    self._device,
                    'No service is registered under the name "%s", cannot resume.'
                    % name)
            service = self._service_objects[name]
            if not service.is_alive:
                service.resume()

    def __getattr__(self, name):
        """Syntactic sugar to enable direct access of service objects by alias.

        Args:
            name: string, the alias a service object was registered under.
        """
        if self.has_service_by_name(name):
            return self._service_objects[name]
        return self.__getattribute__(name)
