'''
Created on June 30, 2018

This file is subject to the terms and conditions defined in the
file 'LICENSE.txt', which is part of this source code package.

@author: <NAME>
'''

# All microservices must extend the Intelligence class
from intelligence.intelligence import Intelligence

# Import an EntryDevice so we can see if the device that's currently sending a measurement is an instance of this.
from devices.entry.entry import EntryDevice


class LocationNotificationMicroserivce(Intelligence):
    """
    This microservice will send an HTML-based email using a local custom template when your mode changes. It will include an inline image attachment.

    The template is loaded from `email_template.vm`.

    An image is loaded from `inline_image.png`, and then this image is transformed into base-64 encoding and included as an attachment in the email.
    The image is referenced by the template in a way that the image is rendered inside the email.
    """
    def __init__(self, botengine, parent):
        """
        Instantiate this object
        :param parent: Parent object, either a location or a device object.
        """
        # Always initialize your parent Intelligence class at the beginning
        Intelligence.__init__(self, botengine, parent)

    def initialize(self, botengine):
        """
        Initialize
        :param botengine: BotEngine environment
        """
        return

    def destroy(self, botengine):
        """
        This device or object is getting permanently deleted - it is no longer in the user's account.
        :param botengine: BotEngine environment
        """
        return

    def get_html_summary(self, botengine, oldest_timestamp_ms, newest_timestamp_ms, test_mode=False):
        """
        Return a human-friendly HTML summary of insights or status of this intelligence module to report in weekly and test mode emails
        :param botengine: BotEngine environment
        :param oldest_timestamp_ms: Oldest timestamp in milliseconds to summarize
        :param newest_timestamp_ms: Newest timestamp in milliseconds to summarize
        :param test_mode: True to add or modify details for test mode, instead of a general weekly summary
        """
        return ""

    def mode_updated(self, botengine, current_mode):
        """
        Mode was updated
        :param botengine: BotEngine environment
        :param current_mode: Current mode
        :param current_timestamp: Current timestamp
        """
        # First we need to identify this bots directory so we can extract the files that we included.
        import os
        my_app_directory = os.path.dirname(os.path.realpath(__file__))

        # Open the local email template
        with open(my_app_directory + '/email_template.vm', 'r') as email_template:
            template = email_template.read()

        # This is the correct way to check for an explicit mode:
        #
        #    if "HOME" is in current_mode:
        #        # GOOD
        #        ...
        #
        # Do not do this:
        #
        #    if "HOME" == current_mode:
        #        # BAD
        #        ...
        #
        # Because the official mode string can include other attributes, like "AWAY.SILENT" and "HOME.DURESS".
        if "HOME" in current_mode:
            template = template.replace("$message", "Welcome Home.")
        elif "AWAY" in current_mode:
            template = template.replace("$message", "Goodbye.")
        elif "STAY" in current_mode:
            template = template.replace("$message", "Protecting your perimeter.")
        elif "SLEEP" in current_mode:
            template = template.replace("$message", "Goodnight.")
        elif "VACATION" in current_mode:
            template = template.replace("$message", "Have a nice trip.")
        else:
            template = template.replace("$message", "You are now in {} mode.")

        # Load a picture and base64-encode it
        import base64
        with open(my_app_directory + "/inline_image.png", "rb") as image_file:
            encoded_image = base64.b64encode(image_file.read())
            utf8_decoded_image = encoded_image.decode('utf-8')

        # Form a list of attachments, and then add the image's base64-encoded utf-8 string as an attachment.
        attachments = []
        botengine.add_email_attachment(attachments, "inline_image.png", utf8_decoded_image, "image/png", "inlineImageId")

        # Send the messages. Messages are implied to the user only, unless otherwise specified
        botengine.notify(
                        push_content = "Your bot says you are now in {} mode.".format(current_mode),
                        push_sound = None,
                        email_subject = "Email notification from your bot!",
                        email_content = template,
                        email_html = True,
                        email_attachments = attachments
                        )

        botengine.get_logger().info("\t=> Push and email notifications sent on mode change")


    def device_measurements_updated(self, botengine, device_object):
        """
        Device was updated
        :param botengine: BotEngine environment
        :param device_object: Device object that was updated
        """
        return


    def device_metadata_updated(self, botengine, device_object):
        """
        Evaluate a device that is new or whose goal/scenario was recently updated
        :param botengine: BotEngine environment
        :param device_object: Device object that was updated
        """
        # Device metadata can get updated multiple times in one execution. Uncomment this line if you'd like to see it.
        #botengine.get_logger().info("LOCATION_realtimedata_microservice: device_metadata_updated from '{}'".format(device_object.description))
        return

    def device_alert(self, botengine, device_object, alert_type, alert_params):
        """
        Device sent an alert.
        When a device disconnects, it will send an alert like this:  [{u'alertType': u'status', u'params': [{u'name': u'deviceStatus', u'value': u'2'}], u'deviceId': u'eb10e80a006f0d00'}]
        When a device reconnects, it will send an alert like this:  [{u'alertType': u'on', u'deviceId': u'eb10e80a006f0d00'}]
        :param botengine: BotEngine environment
        :param device_object: Device object that sent the alert
        :param alert_type: Type of alert
        """
        return

    def device_deleted(self, botengine, device_object):
        """
        Device is getting deleted
        :param botengine: BotEngine environment
        :param device_object: Device object that is getting deleted
        """
        return

    def question_answered(self, botengine, question):
        """
        The user answered a question
        :param botengine: BotEngine environment
        :param question: Question object
        """
        return

    def datastream_updated(self, botengine, address, content):
        """
        Data Stream Message Received
        :param botengine: BotEngine environment
        :param address: Data Stream address
        :param content: Content of the message
        """
        return

    def schedule_fired(self, botengine, schedule_id):
        """
        The bot executed on a hard coded schedule specified by our runtime.json file
        :param botengine: BotEngine environment
        :param schedule_id: Schedule ID that is executing from our list of runtime schedules
        """
        return

    def timer_fired(self, botengine, argument):
        """
        The bot's intelligence timer fired
        :param botengine: Current botengine environment
        :param argument: Argument applied when setting the timer
        """
        return

    def file_uploaded(self, botengine, device_object, file_id, filesize_bytes, content_type, file_extension):
        """
        A device file has been uploaded
        :param botengine: BotEngine environment
        :param device_object: Device object that uploaded the file
        :param file_id: File ID to reference this file at the server
        :param filesize_bytes: The file size in bytes
        :param content_type: The content type, for example 'video/mp4'
        :param file_extension: The file extension, for example 'mp4'
        """
        return

    def coordinates_updated(self, botengine, latitude, longitude):
        """
        Approximate coordinates of the parent proxy device object have been updated
        :param latitude: Latitude
        :param longitude: Longitude
        """
        return

