# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.

from userale.version import __version__
from userale.format import JsonFormatter
from PyQt5.QtCore import QObject, QEvent, QTimer
from collections import Counter
import datetime, time
import logging
import uuid
import atexit
import random

_ = JsonFormatter

class Ale (QObject):
    """
    ALE Library
    """

    def __init__(self, 
                 output="userale.log",
                 user=None,
                 session=None,
                 toolname=None,
                 toolversion=None,
                 keylog=False,
                 interval=5000,
                 resolution=100,   
                 shutoff=[]):
        """
        :param output: [str] The file or url path to which logs will be sent.
        :param user: [str] Identifier for the user of the application.
        :param session: [str] Session tag to track same user with multiple sessions. If a session is not provided, one will be created.
        :param toolname: [str] The application name.
        :param toolversion: [str] The application version.
        :param keylog: [bool] Should detailed key logs be recorded. Default is False.
        :param interval: [int] The minimum time interval in ms between batch transmission of logs. Default is 5000ms.
        :param resolution: [int] Delay in ms between instances of high frequency logs like mousemoves, scrolls, etc. Default is 100ms (10Hz). Entering 0 disables it.
        :param shutoff: [list] Turn off logging for specific events.
    
        An example log will appear like this:

        .. code-block:: python

            {
                'target': 'testLineEdit',
                'path': ['Example', 'testLineEdit'],
                'clientTime': '2016-08-03 16:12:03.460573',
                'location': {'x': 82, 'y': 0},
                'type': 'mousemove',
                'userAction': 'true',
                'details' : {},
                'userId': 'userABC1234',
                'session': '5ee42ccc-852c-44d9-a937-28d7901e4ead',
                'toolName': 'myApplication',
                'toolVersion': '3.5.0',
                'useraleVersion': '0.1.0'
            }
        """

        QObject.__init__(self)
        # UserAle Configuration
        self.output = output
        self.user = user
        # Autogenerate session id if session is not configured
        self.session = session if session is not None else str (uuid.uuid4 ())
        self.toolname = toolname
        self.toolversion = toolversion
        self.keylog = keylog
        self.interval = interval
        self.resolution = resolution
        self.shutoff = shutoff

        # Configure logging
        self.logger = logging
        self.logger.basicConfig(level=logging.INFO,
                                filename=self.output,
                                format='%(message)s')

        # Mapping of all events to methods
        self.map = {
            QEvent.MouseButtonPress: {'mousedown': self.handleMouseEvents},
            QEvent.MouseButtonRelease: {'mouseup': self.handleMouseEvents},
            QEvent.MouseMove: {'mousemove': self.handleMouseEvents},
            QEvent.Enter: {'mouseenter': self.handleMouseEvents},
            QEvent.Leave: {'mouseleave': self.handleMouseEvents},
            QEvent.DragEnter: {'dragenter': self.handleDragEvents},
            QEvent.DragLeave: {'dragleave': self.handleDragEvents},
            QEvent.DragMove: {'dragmove': self.handleDragEvents},
            QEvent.Drop: {'dragdrop': self.handleDragEvents},
            QEvent.KeyPress: {'keypress': self.handleKeyEvents},
            QEvent.KeyRelease: {'keyrelease': self.handleKeyEvents},
            QEvent.Move: {'move': self.handleMoveEvents},
            QEvent.Resize: {'resize': self.handleResizeEvents},
            QEvent.Scroll: {'scroll': self.handleScrollEvents}
        }

        # Turn on/off keylogging & remove specific filters
        for key in list (self.map):
            name = list (self.map[key]) [0]
            if name in self.shutoff or (not self.keylog and (name == 'keypress' or name == 'keyrelease')):
                del self.map [key]

        # Sample rate 
        self.hfreq = [QEvent.MouseMove, QEvent.DragMove, QEvent.Scroll]

        # Sample Timer
        if self.resolution > 0:
            self.timer = QTimer ()
            self.timer.timeout.connect (self.aggregate)
            self.timer.start (self.resolution)

        # Batch transmission of logs
        self.intervalID = self.startTimer (self.interval)

        # Temporary storage for logs
        self.logs = []
        self.hlogs = []

        # Register Exit hanldler
        atexit.register (self.cleanup)

    def eventFilter (self, object, event):
        '''
        :param object: [QObject] The object being watched.
        :param event: [QEvent] The event triggered by a user action.
        :return: [bool] Propagate filter up if other objects needs to be handled
        
        Filters events for the watched widget.
        '''

        data = None
        t = event.type ()

        if t in self.map:        
            # Handle leaf node 
            if len(object.children ()) == 0:
            # if object.isWidgetType () and len(object.children ()) == 0:
                name = list (self.map [t].keys())[0]
                method = list (self.map [t].values())[0]
                data = method (name, event, object)

            # Handle window object
            else:
                # How to handle events on windows? It comes before the child widgets in window? 
                # Either an event actually ocurred on window or is an effect of event propagation. 
                pass

        # Filter data to higher or lower priority list
        if data is not None:
            if self.resolution > 0 and t in self.hfreq and t in self.map:   # data is in watched list and is a high frequency log
                self.hlogs.append (data)
            else:
                self.logs.append (data)

        return super (Ale, self).eventFilter (object, event)

    def cleanup (self):
        '''
        Clean up any dangling logs in self.logs or self.hlogs
        '''
        if self.resolution > 0:
            self.aggregate ()
        self.dump ()

    def timerEvent (self, event):
        '''
        :param object: [list] List of events
        :return: [void] Emit events to file

        Routinely dump data to file or send over the network
        '''

        self.dump ()

    def dump (self):
        '''
        Write log data to file
        '''

        if len (self.logs) > 0:
            # print ("dumping {} logs".format (len (self.logs)))
            self.logger.info (_(self.logs))
            self.logs = [] # Reset logs

    def aggregate (self):
        '''
        Sample high frequency logs at self.resolution. High frequency logs are consolidated down to a single log event 
        to be emitted later
        '''
        
        if len (self.hlogs) > 0:
            # print ("agging {} logs".format (len (self.hlogs)))
            # Given target, path, location [median], return aggregate
            # agg_events = Counter (self.hlogs)
            # # Iterate over collapsed collection to generate a single log per event
            # # Location information is lost due to consolidation. 
            # # @todo develop hashing funciton or new counter to generate avg x and avg y location
            # for event, counter in agg_events.items ():
            #     # aggdata = self.__create_msg (event[0], event[1], event[2], details={"count" : counter}) 
            #     aggdata = {"target": event[0], "type" : event[1], "details": {"count": counter}}
            #     print (aggdata)
            #     self.logs.append (aggdata)
            self.logs.append (random.choice (self.hlogs))
            self.hlogs = []
        
    def getSender (self, object):
        '''
        :param object: [QObject] The object being watched.
        :return: [QObject] The QObject 

        Fetch the QObject who triggered the event
        '''

        sender = None
        try:
            sender = object.sender () if object.sender() is not None else None   
        except:
            pass
        return sender

    def getSelector (self, object):
        """
        :param object: [QObject] The base class for all Qt objects.
        :return: [str] The Qt object's name

        Get target object's name (object defined by user or object's meta class name). If object is null, return "Undefined".
        """
        try:
            return object.objectName () if object.objectName () else object.staticMetaObject.className ()
        except:
            return "Undefined"

    def getLocation (self, event):
        """
        :param event: [QEvent] The base class for all event classes.
        :return: [dict] A dictionary representation of the x and y positions of the mouse cursor.

        Grab the x and y position of the mouse cursor, relative to the widget that received the event.
        """

        try: 
            return {"x" : event.pos ().x (), "y" : event.pos ().y ()}
        except:
            return None

    def getPath (self, object):
        """
        :param object: [QObject] The base class for all Qt objects.
        :return: [list] List of QObjects.

        Generate the entire object hierachy from root to leaf node. 
        """

        try:
            if object.parent() is not None:
                return self.getPath (object.parent()) + [self.getSelector (object)]
            else:
                return [self.getSelector (object)]
        except:
            return "Undefined"
        
    def getClientTime (self):
        """
        :return: [str] String representation of the time the event was captured.
        
        Capture the time the event was captured in milliseconds since the UNIX epoch (January 1, 1970 00:00:00 UTC)
        """

        return int (time.time() * 1000)

    def handleMouseEvents (self, event_type, event, object):
        """
        :param event_type: [str] The string representation of the type of event being triggered by the user.
        :param event: [QEvent] The base class for all event classes.
        :param object: [QObject] The base class for all Qt objects.
        :return: [dict] A userale log describing a mouse event.

        Returns the userale log representing all mouse event data. 
        """

        details = {}
        return self.__create_msg (event_type, event, object, details=details)

    def handleKeyEvents (self, event_type, event, object):
        """
        :param event_type: [str] The string representation of the type of event being triggered by the user.
        :param event: [QEvent] The base class for all event classes.
        :param object: [QObject] The base class for all Qt objects.
        :return: [dict] A userale log describing a key event.

        Returns the userale log representing all key events, including key name and key code.
        """

        details = {"key" : event.text (), "keycode" : event.key ()}
        return self.__create_msg (event_type, event, object, details=details)

    def handleDragEvents (self, event_type, event, object):
        """
        :param event_type: [str] The string representation of the type of event being triggered by the user.
        :param event: [QEvent] The base class for all event classes.
        :param object: [QObject] The base class for all Qt objects.
        :return: [dict] A userale log describing a drag event.

        Returns the userale log representing all drag events. 
        """

        details = {}

        try:
            details ["source"] = self.getSelector (event.source ())      
        except:
            details ["source"] = None

        return self.__create_msg (event_type, event, object, details=details)

    def handleMoveEvents (self, event_type, event, object):
        """
        :param event_type: [str] The string representation of the type of event being triggered by the user.
        :param event: [QEvent] The base class for all event classes.
        :param object: [QObject] The base class for all Qt objects.
        :return: [dict] A userale log describing a drag event.

        Returns the userale log representing all move events. 
        """

        details = {"oldPos" : {"x" : event.oldPos ().x (), "y" : event.oldPos ().y ()}}
        return self.__create_msg (event_type, event, object, details=details)
        
    def handleResizeEvents (self, event_type, event, object):
        """
        :param event_type: [str] The string representation of the type of event being triggered by the user.
        :param event: [QEvent] The base class for all event classes.
        :param object: [QObject] The base class for all Qt objects.
        :return: [dict] A userale log describing a resize event.

        Returns the userale log representing all resize events. 
        """

        details = {"size" : {"height" : event.size ().height (), "width" : event.size ().width ()},
                   "oldSize":  {"height" : event.oldSize ().height (), "width" : event.oldSize ().width ()}}
        return self.__create_msg (event_type, event, object, details=details)

    def handleScrollEvents (self, event_type, event, object):
        """
        :param event_type: [str] The string representation of the type of event being triggered by the user.
        :param event: [QEvent] The base class for all event classes.
        :param object: [QObject] The base class for all Qt objects.
        :return: [dict] A userale log describing a scroll event.

        Returns the userale log representing all scroll events. 
        """

        return self.__create_msg (event_type, event, object)

    def __create_msg (self, event_type, event, object, details={}):
        """
        Geneate UserAle log describing an event.
        """

        data = {
            "target": self.getSelector (object),
            "path": self.getPath (object),
            "clientTime": self.getClientTime (),    
            "location": self.getLocation (event),
            "type": event_type ,
            "userAction": True,   # legacy field
            "details" : details,
            "userId": self.user,
            "session": self.session,
            "toolName": self.toolname,
            "toolVersion": self.toolversion,
            "useraleVersion": __version__
        }

        return data
