# 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/models.py
# GCM_PLATFORM = 'gcm'
# 
# class ResponseLog(models.Model):
#     """
#     Model for logging info about the device response.
#     """
#     platform = models.CharField(choices=PLATFORM_CHOICES, max_length=10)
#     roundtrip_time = models.FloatField()
#     available = models.BooleanField()
#     date = models.DateTimeField(auto_now_add=True)
# 
# Path: main/prometheus/consts.py
# ACTION_KEY = 'action'
# 
# APP_VERSION_KEY = 'app_version'
# 
# CODEC_KEY = 'codec'
# 
# CONNECTION_TYPE_KEY = 'connection_type'
# 
# DIRECTION_KEY = 'direction'
# 
# FAILED_REASON_KEY = 'failed_reason'
# 
# HANGUP_REASON_KEY = 'hangup_reason'
# 
# MOS_KEY = 'mos'
# 
# NETWORK_KEY = 'network'
# 
# NETWORK_OPERATOR_KEY = 'network_operator'
# 
# OS_KEY = 'os'
# 
# OS_VERSION_KEY = 'os_version'
# 
# VIALER_CALL_FAILURE_TOTAL_KEY = 'vialer_call_failure_total'
# 
# VIALER_CALL_SUCCESS_TOTAL_KEY = 'vialer_call_success_total'
# 
# VIALER_HANGUP_REASON_TOTAL_KEY = 'vialer_hangup_reason_total'
# 
# VIALER_MIDDLEWARE_INCOMING_CALL_FAILED_TOTAL_KEY = 'vialer_middleware_incoming_call_failed_total'
# 
# VIALER_MIDDLEWARE_INCOMING_CALL_SUCCESS_TOTAL_KEY = 'vialer_middleware_incoming_call_success_total'
# 
# VIALER_MIDDLEWARE_PUSH_NOTIFICATION_FAILED_TOTAL_KEY = 'vialer_middleware_push_notification_failed_total'
# 
# VIALER_MIDDLEWARE_PUSH_NOTIFICATION_SUCCESS_TOTAL_KEY = 'vialer_middleware_push_notification_success_total'


import os
import sys
import django
import time
from ast import literal_eval
from random import randint, random
from django.conf import settings
from django.db import connection, DatabaseError
from prometheus_client import Counter, Gauge, start_http_server
from raven.contrib.django.models import client as raven_client
from redis import RedisError
from rediscluster.exceptions import RedisClusterException
from app.cache import RedisClusterCache
from app.models import GCM_PLATFORM, ResponseLog
from main.prometheus.consts import (
    ACTION_KEY,
    APP_VERSION_KEY,
    CODEC_KEY,
    CONNECTION_TYPE_KEY,
    DIRECTION_KEY,
    FAILED_REASON_KEY,
    HANGUP_REASON_KEY,
    MOS_KEY,
    NETWORK_KEY,
    NETWORK_OPERATOR_KEY,
    OS_KEY,
    OS_VERSION_KEY,
    VIALER_CALL_FAILURE_TOTAL_KEY,
    VIALER_CALL_SUCCESS_TOTAL_KEY,
    VIALER_HANGUP_REASON_TOTAL_KEY,
    VIALER_MIDDLEWARE_INCOMING_CALL_FAILED_TOTAL_KEY,
    VIALER_MIDDLEWARE_INCOMING_CALL_SUCCESS_TOTAL_KEY,
    VIALER_MIDDLEWARE_PUSH_NOTIFICATION_FAILED_TOTAL_KEY,
    VIALER_MIDDLEWARE_PUSH_NOTIFICATION_SUCCESS_TOTAL_KEY)
            connection_type=value_dict[CONNECTION_TYPE_KEY],
            direction=value_dict[DIRECTION_KEY],
            failed_reason=value_dict[FAILED_REASON_KEY],
            network=value_dict[NETWORK_KEY],
            network_operator=value_dict.get(NETWORK_OPERATOR_KEY, ''),
            os=value_dict[OS_KEY],
            os_version=value_dict[OS_VERSION_KEY],
        ).inc()

    # Trim the list, this means that the values that are outside
    # of the selected range are deleted. In this case we are keeping
    # all of the values we did not yet process in the list.
    REDIS_CLUSTER_CLIENT.client.ltrim(VIALER_CALL_FAILURE_TOTAL_KEY, list_length, -1)


def increment_vialer_hangup_reason_metric_counter():
    """
        Function that increments the vialer_hangup_total counter.
        """
    # Get the length of the list in redis.
    list_length = REDIS_CLUSTER_CLIENT.client.llen(VIALER_HANGUP_REASON_TOTAL_KEY)

    # Get the values from the list in redis.
    data_list = REDIS_CLUSTER_CLIENT.client.lrange(VIALER_HANGUP_REASON_TOTAL_KEY, 0, list_length)

    for value_str in data_list:
        # Parse the string to a dict.
        value_dict = literal_eval(value_str)
        VIALER_HANGUP_REASON_TOTAL.labels(
            app_version=value_dict[APP_VERSION_KEY],

# 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/models.py
# GCM_PLATFORM = 'gcm'
# 
# class ResponseLog(models.Model):
#     """
#     Model for logging info about the device response.
#     """
#     platform = models.CharField(choices=PLATFORM_CHOICES, max_length=10)
#     roundtrip_time = models.FloatField()
#     available = models.BooleanField()
#     date = models.DateTimeField(auto_now_add=True)
# 
# Path: main/prometheus/consts.py
# ACTION_KEY = 'action'
# 
# APP_VERSION_KEY = 'app_version'
# 
# CODEC_KEY = 'codec'
# 
# CONNECTION_TYPE_KEY = 'connection_type'
# 
# DIRECTION_KEY = 'direction'
# 
# FAILED_REASON_KEY = 'failed_reason'
# 
# HANGUP_REASON_KEY = 'hangup_reason'
# 
# MOS_KEY = 'mos'
# 
# NETWORK_KEY = 'network'
# 
# NETWORK_OPERATOR_KEY = 'network_operator'
# 
# OS_KEY = 'os'
# 
# OS_VERSION_KEY = 'os_version'
# 
# VIALER_CALL_FAILURE_TOTAL_KEY = 'vialer_call_failure_total'
# 
# VIALER_CALL_SUCCESS_TOTAL_KEY = 'vialer_call_success_total'
# 
# VIALER_HANGUP_REASON_TOTAL_KEY = 'vialer_hangup_reason_total'
# 
# VIALER_MIDDLEWARE_INCOMING_CALL_FAILED_TOTAL_KEY = 'vialer_middleware_incoming_call_failed_total'
# 
# VIALER_MIDDLEWARE_INCOMING_CALL_SUCCESS_TOTAL_KEY = 'vialer_middleware_incoming_call_success_total'
# 
# VIALER_MIDDLEWARE_PUSH_NOTIFICATION_FAILED_TOTAL_KEY = 'vialer_middleware_push_notification_failed_total'
# 
# VIALER_MIDDLEWARE_PUSH_NOTIFICATION_SUCCESS_TOTAL_KEY = 'vialer_middleware_push_notification_success_total'


# Path: main/prometheus/prometheus.py
import os
import sys
import django
import time
from ast import literal_eval
from random import randint, random
from django.conf import settings
from django.db import connection, DatabaseError
from prometheus_client import Counter, Gauge, start_http_server
from raven.contrib.django.models import client as raven_client
from redis import RedisError
from rediscluster.exceptions import RedisClusterException
from app.cache import RedisClusterCache
from app.models import GCM_PLATFORM, ResponseLog
from main.prometheus.consts import (
    ACTION_KEY,
    APP_VERSION_KEY,
    CODEC_KEY,
    CONNECTION_TYPE_KEY,
    DIRECTION_KEY,
    FAILED_REASON_KEY,
    HANGUP_REASON_KEY,
    MOS_KEY,
    NETWORK_KEY,
    NETWORK_OPERATOR_KEY,
    OS_KEY,
    OS_VERSION_KEY,
    VIALER_CALL_FAILURE_TOTAL_KEY,
    VIALER_CALL_SUCCESS_TOTAL_KEY,
    VIALER_HANGUP_REASON_TOTAL_KEY,
    VIALER_MIDDLEWARE_INCOMING_CALL_FAILED_TOTAL_KEY,
    VIALER_MIDDLEWARE_INCOMING_CALL_SUCCESS_TOTAL_KEY,
    VIALER_MIDDLEWARE_PUSH_NOTIFICATION_FAILED_TOTAL_KEY,
    VIALER_MIDDLEWARE_PUSH_NOTIFICATION_SUCCESS_TOTAL_KEY)

            connection_type=value_dict[CONNECTION_TYPE_KEY],
            direction=value_dict[DIRECTION_KEY],
            failed_reason=value_dict[FAILED_REASON_KEY],
            network=value_dict[NETWORK_KEY],
            network_operator=value_dict.get(NETWORK_OPERATOR_KEY, ''),
            os=value_dict[OS_KEY],
            os_version=value_dict[OS_VERSION_KEY],
        ).inc()

    # Trim the list, this means that the values that are outside
    # of the selected range are deleted. In this case we are keeping
    # all of the values we did not yet process in the list.
    REDIS_CLUSTER_CLIENT.client.ltrim(VIALER_CALL_FAILURE_TOTAL_KEY, list_length, -1)


def increment_vialer_hangup_reason_metric_counter():
    """
        Function that increments the vialer_hangup_total counter.
        """
    # Get the length of the list in redis.
    list_length = REDIS_CLUSTER_CLIENT.client.llen(VIALER_HANGUP_REASON_TOTAL_KEY)

    # Get the values from the list in redis.
    data_list = REDIS_CLUSTER_CLIENT.client.lrange(VIALER_HANGUP_REASON_TOTAL_KEY, 0, list_length)

    for value_str in data_list:
        # Parse the string to a dict.
        value_dict = literal_eval(value_str)
        VIALER_HANGUP_REASON_TOTAL.labels(
            app_version=value_dict[APP_VERSION_KEY],

            connection_type=value_dict[CONNECTION_TYPE_KEY],