"""
ping_celery management command.
Prints '0;OK' if all ok.
Prints '2;{error description}' in case of error.
"""
import time

from django.core.management.base import BaseCommand
from django.utils import timezone

from pypi.ping.management.commands.ping import PingException
from pypi.ping.models import TouchMe


PING_MAX_LAG = 5 * 60


class Obsolete(PingException):

    """
    too much time passed from last TouchMe object update
    """

    def __str__(self):
        return 'Celery stopped working'


class Command(BaseCommand):
    help = ('Trying to determine if celery running scheduled tasks correctly.'
            'Return status in monrun-compliant format')
    requires_model_validation = False

    def handle(self, *args, **options):
        """
        Проверка timestamp последнего обновления объекта TouchMe в MySQL.
        Объект TouchMe должна обновлять Celery в периодическом таске.
        Если время последнего обновления было сликшком давно ("давно" контролируется через
        settings.PING_MAX_LAG) - алярма!
        """
        try:
            try:
                touch_object = TouchMe.objects.get()
            except TouchMe.DoesNotExist:
                raise PingException('TouchMe object doesn\'t exists')
            else:
                # modified at in unix time
                modified_dt = int(time.mktime(touch_object.modified_at.timetuple()))
                now_timestamp = int(time.mktime(timezone.now().timetuple()))
                # get delta of last touch time and now
                delta = now_timestamp - modified_dt

                if delta < 0:
                    # seems like somewhere we have wrong time settings
                    raise PingException(
                        f'Wrong data: TouchMe was modified '
                        f'at {modified_dt} '
                        f'and now is {now_timestamp}'
                    )

                # check if Celery is working
                if not PING_MAX_LAG > delta:
                    raise Obsolete(PING_MAX_LAG)

        except PingException as exc:
            print(f'2;{exc}')

        except Exception as exc:
            print(f'2;Unhandled exception:{exc}')

        else:
            print('0;OK')
