# Path: app/cache.py
# class RedisClusterCache(object):
#     """
#     Class used for accessing the redis cluster used for caching.
#     """
#     def __init__(self):
#         self.client = self._create_client()
# 
#     def _create_client(self):
#         """
#         Function to connect to the redis cluster and init the client.
#         """
#         server_list = settings.REDIS_SERVER_LIST.replace(' ', '').split(',')
# 
#         nodes = []
#         for server in server_list:
#             if ':' not in server:
#                 continue
#             host, port = server.split(':')
#             nodes.append({'host': host, 'port': port})
# 
#         return StrictRedisCluster(startup_nodes=nodes, decode_responses=True)
# 
#     def get(self, key):
#         return self.client.get(key)
# 
#     def exists(self, key):
#         return self.client.exists(key)
# 
#     def set(self, key, value, timeout=DEFAULT_TIMEOUT):
#         self.client.set(key, value, timeout)
# 
# Path: app/utils.py
# def log_middleware_information(log_statement, dict_with_variables, log_level, device=None):
#     """
#     Function that handles the logging for the middleware.
# 
#     Args:
#         log_statement (str): The message to log.
#         dict_with_variables (OrderedDict): OrderedDict that contains the
#             variables we want to insert into the logging statement.
#         log_level (int): The level on which to log.
#         device (Device): The device for which we want to log to Logentries.
#     """
#     remote_logging_id = device.remote_logging_id if device and device.remote_logging_id else 'No remote logging ID'
#     django_log_statement = fill_log_statement(log_statement, dict_with_variables)
#     django_logger.log(log_level, '{0} - middleware - {1}'.format(remote_logging_id, django_log_statement))
# 
#     if device and device.remote_logging_id:
#         log_statement = fill_log_statement(log_statement, dict_with_variables, anonymize=True)
#         logentries_token = device.app.logentries_token
#         log_to_logentries(log_statement, log_level, logentries_token, device, remote_logging_id)
#         if device.app.partner_logentries_token:
#             # Log to the Logentries environment of the partner with a different token.
#             logentries_token = device.app.partner_logentries_token
#             log_to_logentries(log_statement, log_level, logentries_token, device, remote_logging_id)
# 
# Path: app/models.py
# ANDROID_PLATFORM = 'android'
# 
# APNS_PLATFORM = 'apns'
# 
# GCM_PLATFORM = 'gcm'


from collections import OrderedDict
from time import time
from urllib.parse import urljoin
from apns2.client import APNsClient
from apns2.errors import APNsException, BadDeviceToken, DeviceTokenNotForTopic, Unregistered
from apns2.payload import Payload
from django.conf import settings
from gcm.gcm import GCM, GCMAuthenticationException
from pyfcm import FCMNotification
from pyfcm.errors import AuthenticationError, FCMServerError, InternalPackageError
from app.cache import RedisClusterCache
from app.utils import log_middleware_information
from .models import ANDROID_PLATFORM, APNS_PLATFORM, GCM_PLATFORM
import datetime
import logging
import os
        send_apns_message(device, device.app, TYPE_CALL, data)
    elif device.app.platform == GCM_PLATFORM:
        send_gcm_message(device, device.app, TYPE_CALL, data)
    elif device.app.platform == ANDROID_PLATFORM:
        send_fcm_message(device, device.app, TYPE_CALL, data)
    else:
        log_middleware_information(
            '{0} | Trying to sent \'call\' notification to unknown platform:{1} device:{2}',
            OrderedDict([
                ('unique_key', unique_key),
                ('platform', device.app.platform),
                ('token', device.token),
            ]),
            logging.WARNING,
            device=device,
        )


def send_text_message(device, app, message):
    """
    Function to send a push notification with a message.

    Args:
        device (Device): A Device object.
        message (string): The message that needs to be send to the device.
    """
    if app.platform == APNS_PLATFORM:
        send_apns_message(device, app, TYPE_MESSAGE, {'message': message})
    elif app.platform == GCM_PLATFORM:
        send_gcm_message(device, app, TYPE_MESSAGE, {'message': message})

# Path: app/cache.py
# class RedisClusterCache(object):
#     """
#     Class used for accessing the redis cluster used for caching.
#     """
#     def __init__(self):
#         self.client = self._create_client()
# 
#     def _create_client(self):
#         """
#         Function to connect to the redis cluster and init the client.
#         """
#         server_list = settings.REDIS_SERVER_LIST.replace(' ', '').split(',')
# 
#         nodes = []
#         for server in server_list:
#             if ':' not in server:
#                 continue
#             host, port = server.split(':')
#             nodes.append({'host': host, 'port': port})
# 
#         return StrictRedisCluster(startup_nodes=nodes, decode_responses=True)
# 
#     def get(self, key):
#         return self.client.get(key)
# 
#     def exists(self, key):
#         return self.client.exists(key)
# 
#     def set(self, key, value, timeout=DEFAULT_TIMEOUT):
#         self.client.set(key, value, timeout)
# 
# Path: app/utils.py
# def log_middleware_information(log_statement, dict_with_variables, log_level, device=None):
#     """
#     Function that handles the logging for the middleware.
# 
#     Args:
#         log_statement (str): The message to log.
#         dict_with_variables (OrderedDict): OrderedDict that contains the
#             variables we want to insert into the logging statement.
#         log_level (int): The level on which to log.
#         device (Device): The device for which we want to log to Logentries.
#     """
#     remote_logging_id = device.remote_logging_id if device and device.remote_logging_id else 'No remote logging ID'
#     django_log_statement = fill_log_statement(log_statement, dict_with_variables)
#     django_logger.log(log_level, '{0} - middleware - {1}'.format(remote_logging_id, django_log_statement))
# 
#     if device and device.remote_logging_id:
#         log_statement = fill_log_statement(log_statement, dict_with_variables, anonymize=True)
#         logentries_token = device.app.logentries_token
#         log_to_logentries(log_statement, log_level, logentries_token, device, remote_logging_id)
#         if device.app.partner_logentries_token:
#             # Log to the Logentries environment of the partner with a different token.
#             logentries_token = device.app.partner_logentries_token
#             log_to_logentries(log_statement, log_level, logentries_token, device, remote_logging_id)
# 
# Path: app/models.py
# ANDROID_PLATFORM = 'android'
# 
# APNS_PLATFORM = 'apns'
# 
# GCM_PLATFORM = 'gcm'


# Path: app/push.py
from collections import OrderedDict
from time import time
from urllib.parse import urljoin
from apns2.client import APNsClient
from apns2.errors import APNsException, BadDeviceToken, DeviceTokenNotForTopic, Unregistered
from apns2.payload import Payload
from django.conf import settings
from gcm.gcm import GCM, GCMAuthenticationException
from pyfcm import FCMNotification
from pyfcm.errors import AuthenticationError, FCMServerError, InternalPackageError
from app.cache import RedisClusterCache
from app.utils import log_middleware_information
from .models import ANDROID_PLATFORM, APNS_PLATFORM, GCM_PLATFORM
import datetime
import logging
import os

        send_apns_message(device, device.app, TYPE_CALL, data)
    elif device.app.platform == GCM_PLATFORM:
        send_gcm_message(device, device.app, TYPE_CALL, data)
    elif device.app.platform == ANDROID_PLATFORM:
        send_fcm_message(device, device.app, TYPE_CALL, data)
    else:
        log_middleware_information(
            '{0} | Trying to sent \'call\' notification to unknown platform:{1} device:{2}',
            OrderedDict([
                ('unique_key', unique_key),
                ('platform', device.app.platform),
                ('token', device.token),
            ]),
            logging.WARNING,
            device=device,
        )


def send_text_message(device, app, message):
    """
    Function to send a push notification with a message.

    Args:
        device (Device): A Device object.
        message (string): The message that needs to be send to the device.
    """
    if app.platform == APNS_PLATFORM:
        send_apns_message(device, app, TYPE_MESSAGE, {'message': message})
    elif app.platform == GCM_PLATFORM:
        send_gcm_message(device, app, TYPE_MESSAGE, {'message': message})

    elif app.platform == ANDROID_PLATFORM: