#!/usr/bin/env python3
#
#   Copyright 2016 - The Android Open Source Project
#
#   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.

import importlib
import logging
import os

ACTS_CONTROLLER_CONFIG_NAME = "DiagLogger"
ACTS_CONTROLLER_REFERENCE_NAME = "diag_logger"


class DiagLoggerError(Exception):
    """This is the base exception class for errors generated by
    DiagLogger modules.
    """
    pass


def create(configs):
    """Initializes the Diagnotic Logger instances based on the
    provided JSON configuration(s). The expected keys are:

    Package: A package name containing the diagnostic logger
        module. It should be in python path of the environment.
    Type: A first-level type for the Logger, which should correspond
        the name of the module containing the Logger implementation.
    SubType: The exact implementation of the sniffer, which should
        correspond to the name of the class to be used.
    HostLogPath: This is the default directory used to dump any logs
        that are captured or any other files that are stored as part
        of the logging process. It's use is implementation specific,
        but it should be provided by all loggers for completeness.
    Configs: A dictionary specifying baseline configurations of the
        particular Logger. These configurations may be overridden at
        the start of a session.
    """
    objs = []
    for c in configs:
        diag_package_name = c["Package"]  # package containing module
        diag_logger_type = c["Type"]  # module name
        diag_logger_name = c["SubType"]  # class name
        host_log_path = c["HostLogPath"]
        base_configs = c["Configs"]
        module_name = "{}.{}".format(diag_package_name, diag_logger_type)
        module = importlib.import_module(module_name)
        logger_class = getattr(module, diag_logger_name)

        objs.append(logger_class(host_log_path,
                                 None,
                                 config_container=base_configs))
    return objs


def destroy(objs):
    """Stops all ongoing logger sessions, deletes any temporary files, and
    prepares logger objects for destruction.
    """
    for diag_logger in objs:
        try:
            diag_logger.reset()
        except DiagLoggerError:
            # TODO: log if things go badly here
            pass


class DiagLoggerBase():
    """Base Class for Proprietary Diagnostic Log Collection

    The DiagLoggerBase is a simple interface for running on-device logging via
    a standard workflow that can be integrated without the caller actually
    needing to know the details of what logs are captured or how.
    The workflow is as follows:

    1) Create a DiagLoggerBase Object
    2) Call start() to begin an active logging session.
    3) Call stop() to end an active logging session.
    4) Call pull() to ensure all collected logs are stored at
       'host_log_path'
    5) Call reset() to stop all logging and clear any unretrieved logs.
    """

    def __init__(self, host_log_path, logger=None, config_container=None):
        """Create a Diagnostic Logging Proxy Object

        Args:
            host_log_path: File path where retrieved logs should be stored
            config_container: A transparent container used to pass config info
        """
        self.host_log_path = os.path.realpath(os.path.expanduser(
            host_log_path))
        self.config_container = config_container
        if not os.path.isdir(self.host_log_path):
            os.mkdir(self.host_log_path)
        self.logger = logger
        if not self.logger:
            self.logger = logging.getLogger(self.__class__.__name__)

    def start(self, config_container=None):
        """Start collecting Diagnostic Logs

        Args:
            config_container: A transparent container used to pass config info

        Returns:
            A logging session ID that can be later used to stop the session
            For Diag interfaces supporting only one session this is unneeded
        """
        raise NotImplementedError("Base class should not be invoked directly!")

    def stop(self, session_id=None):
        """Stop collecting Diagnostic Logs

        Args:
            session_id: an optional session id provided for multi session
                        logging support

        Returns:
        """
        raise NotImplementedError("Base class should not be invoked directly!")

    def pull(self, session_id=None, out_path=None):
        """Save all cached diagnostic logs collected to the host

        Args:
            session_id: an optional session id provided for multi session
                        logging support

            out_path: an optional override to host_log_path for a specific set
                      of logs

        Returns:
            An integer representing a port number on the host available for adb
            forward.
        """
        raise NotImplementedError("Base class should not be invoked directly!")

    def reset(self):
        """Stop any ongoing logging sessions and clear any cached logs that have
        not been retrieved with pull(). This must delete all session records and
        return the logging object to a state equal to when constructed.
        """
        raise NotImplementedError("Base class should not be invoked directly!")

    def get_log_path(self):
        """Return the log path for this object"""
        return self.host_log_path
