# Path: accounts/models.py
# class ServiceCredentials(models.Model):
#     """
#     This model is intended to store the credentials returned by a service after
#     an Audio Commons account is linked with it. Credentials are intentionally
#     stored in a JSONField to accommodate different types of credentials returned
#     by services. The ACServiceBase authentication methods will be in charge of
#     interpreting the contests of the 'credentials' field.
#     """
# 
#     account = models.ForeignKey(Account, related_name='service_credentials')
#     service_id = models.CharField(max_length=64)
#     credentials = JSONField(null=False, default={})
#     created = models.DateTimeField(auto_now_add=True)
#     modified = models.DateTimeField(auto_now=True)
# 
#     class Meta:
#         verbose_name = _('service credentials')
#         verbose_name_plural = _('service credentials')
#         unique_together = (('account', 'service_id'),)
# 
#     def __str__(self):
#         return 'ServiceCredentials for {0} and {1}'.format(self.account.username, self.service_id)
# 
# Path: services/mgmt.py
# def get_service_by_id(service_id):
#     for service in available_services:
#         if service.id == service_id:
#             return service
#     raise ACServiceDoesNotExist('Service with id {0} does not exist'.format(service_id))
# 
# Path: ac_mediator/exceptions.py
# class ACServiceDoesNotExist(ACException):
#     pass


from django.core.management.base import BaseCommand
from accounts.models import ServiceCredentials
from services.mgmt import get_service_by_id
from ac_mediator.exceptions import ACServiceDoesNotExist
import logging
logger = logging.getLogger('management')


class Command(BaseCommand):
    help = 'Renew access tokens to 3rd party services whose refresh tokens are about to expire. ' \
           'Use as `python manage.py renew_access_tokens`.'

    def add_arguments(self, parser):
        pass

    def handle(self, *args, **options):
        """
        When users link their accounts with third party services, these typically return an access token
        together with a refresh token. Both types of tokens do expire at some point (refresh tokens have
        a longer lifetime). If the access token expires but the refresh token is still valid, the Audio Commons
        mediator can easily get a renewed pair using the refresh token. However if the refresh token expires,
        then there is no way the mediator can renew the token without user intervention and the user will need to
        manually link his account again.
        
        This account will iterate over user accounts and their linked services, and renew access/refresh token
        pairs in the cases when refresh token is about to expire.
        
        More info: https://github.com/AudioCommons/ac-mediator/issues/4
        """

        n_success = 0
        n_failed = 0

        for service_credentials in ServiceCredentials.objects.all():
            try:

# Path: accounts/models.py
# class ServiceCredentials(models.Model):
#     """
#     This model is intended to store the credentials returned by a service after
#     an Audio Commons account is linked with it. Credentials are intentionally
#     stored in a JSONField to accommodate different types of credentials returned
#     by services. The ACServiceBase authentication methods will be in charge of
#     interpreting the contests of the 'credentials' field.
#     """
# 
#     account = models.ForeignKey(Account, related_name='service_credentials')
#     service_id = models.CharField(max_length=64)
#     credentials = JSONField(null=False, default={})
#     created = models.DateTimeField(auto_now_add=True)
#     modified = models.DateTimeField(auto_now=True)
# 
#     class Meta:
#         verbose_name = _('service credentials')
#         verbose_name_plural = _('service credentials')
#         unique_together = (('account', 'service_id'),)
# 
#     def __str__(self):
#         return 'ServiceCredentials for {0} and {1}'.format(self.account.username, self.service_id)
# 
# Path: services/mgmt.py
# def get_service_by_id(service_id):
#     for service in available_services:
#         if service.id == service_id:
#             return service
#     raise ACServiceDoesNotExist('Service with id {0} does not exist'.format(service_id))
# 
# Path: ac_mediator/exceptions.py
# class ACServiceDoesNotExist(ACException):
#     pass


# Path: accounts/management/commands/renew_access_tokens.py
from django.core.management.base import BaseCommand
from accounts.models import ServiceCredentials
from services.mgmt import get_service_by_id
from ac_mediator.exceptions import ACServiceDoesNotExist
import logging

logger = logging.getLogger('management')


class Command(BaseCommand):
    help = 'Renew access tokens to 3rd party services whose refresh tokens are about to expire. ' \
           'Use as `python manage.py renew_access_tokens`.'

    def add_arguments(self, parser):
        pass

    def handle(self, *args, **options):
        """
        When users link their accounts with third party services, these typically return an access token
        together with a refresh token. Both types of tokens do expire at some point (refresh tokens have
        a longer lifetime). If the access token expires but the refresh token is still valid, the Audio Commons
        mediator can easily get a renewed pair using the refresh token. However if the refresh token expires,
        then there is no way the mediator can renew the token without user intervention and the user will need to
        manually link his account again.
        
        This account will iterate over user accounts and their linked services, and renew access/refresh token
        pairs in the cases when refresh token is about to expire.
        
        More info: https://github.com/AudioCommons/ac-mediator/issues/4
        """

        n_success = 0
        n_failed = 0

        for service_credentials in ServiceCredentials.objects.all():
            try:

                service = get_service_by_id(service_credentials.service_id)