import json
import logging

import redis
from celery import shared_task
from django.conf import settings

from core.utils import dtnow
from dashboard.utils import RedisInstances
from incident.models import Incident

_log = logging.getLogger(__name__)

redis_instance = redis.StrictRedis(host=settings.REDIS_HOST, port=settings.REDIS_PORT, db=0)


def update_incs_by_time_statistics():
    """ Task for updating data for incidents by time widget """
    _log.info('Starting update of the incidents statistics')
    # Getting day data from REDIS
    day_data = redis_instance.get(RedisInstances.WIDGET_INCS_BY_TIME_DAY)
    week_data = redis_instance.get(RedisInstances.WIDGET_INCS_BY_TIME_WEEK)
    month_data = redis_instance.get(RedisInstances.WIDGET_INCS_BY_TIME_MONTH)
    year_data = redis_instance.get(RedisInstances.WIDGET_INCS_BY_TIME_YEAR)
    day_data = json.loads(day_data)
    week_data = json.loads(week_data)
    month_data = json.loads(month_data)
    year_data = json.loads(year_data)
    # Getting amount of incidents happened in last 1 minute
    now = dtnow()
    one_minute_gap = dtnow(minutes=-1)
    amount_of_incidents_within_a_minute = Incident.objects.filter(timestamp__range=(one_minute_gap, now)).count()
    # Check if hour is changed
    if one_minute_gap.hour != now.hour:
        day_data.pop(0)
        # Appending new number to the list
        day_data.append(amount_of_incidents_within_a_minute)
        # Updating redis data for the day
        redis_instance.set(RedisInstances.WIDGET_INCS_BY_TIME_DAY, json.dumps(day_data))
    else:
        day_data[-1] = day_data[-1] + amount_of_incidents_within_a_minute
        redis_instance.set(RedisInstances.WIDGET_INCS_BY_TIME_DAY, json.dumps(day_data))
    # Check if day is changed
    if one_minute_gap.day != now.day:
        # Popping the first element of week and month data and appending sum of last day incidents
        week_data.pop(0)
        month_data.pop(0)
        week_data.append(amount_of_incidents_within_a_minute)
        month_data.append(amount_of_incidents_within_a_minute)
        # Setting new REDIS value of week and month incidents list
        redis_instance.set(RedisInstances.WIDGET_INCS_BY_TIME_WEEK, json.dumps(week_data))
        redis_instance.set(RedisInstances.WIDGET_INCS_BY_TIME_MONTH, json.dumps(month_data))
    else:
        week_data[-1] = week_data[-1] + amount_of_incidents_within_a_minute
        month_data[-1] = month_data[-1] + amount_of_incidents_within_a_minute
        # Setting new REDIS value of week and month incidents list
        redis_instance.set(RedisInstances.WIDGET_INCS_BY_TIME_WEEK, json.dumps(week_data))
        redis_instance.set(RedisInstances.WIDGET_INCS_BY_TIME_MONTH, json.dumps(month_data))
    # Check if year is changed
    if one_minute_gap.month != now.month:
        # Popping first element in year list
        year_data.pop(0)
        year_data.append(amount_of_incidents_within_a_minute)
        # Setting new REDIS value of year incidents list
        redis_instance.set(RedisInstances.WIDGET_INCS_BY_TIME_YEAR, json.dumps(year_data))
    else:
        year_data[-1] = year_data[-1] + amount_of_incidents_within_a_minute
        # Setting new REDIS value of year incidents list
        redis_instance.set(RedisInstances.WIDGET_INCS_BY_TIME_YEAR, json.dumps(year_data))


@shared_task
def update_statistics_task():
    # update_events_by_time_statistics()
    update_incs_by_time_statistics()
