# Path: api/request_distributor.py
# def get_request_distributor():
#     return request_distributor
# 
# Path: api/response_aggregator.py
# def get_response_aggregator():
#     return response_aggregator
# 
# Path: services/mgmt.py
# def get_available_services(component=None, exclude=None, include=None):
#     """
#     Get all available services which implement a particular component (or all services if
#     'component' is None). Allows excluding particular services and restricting those from which to filter.
#     :param component: component (mixin) that should be implemented by returned services
#     :param exclude: exclude services passed through this parameter (should be a list of service names)
#     :param include: consider only services passed through this parameter (should be a list of service names)
#     :return: list of matching services (can be empty)
#     """
#     out_services = list()
#     for service in available_services:
#         if component is not None:
#             if component not in service.implemented_components:
#                 continue
#         if exclude is not None:
#             if service.name in exclude:
#                 continue
#         if include is not None:
#             if service.name not in include:
#                 continue
#         out_services.append(service)
#     return out_services
# 
# Path: accounts/models.py
# class Account(AbstractUser):
#     """
#     This is our custom 'User' model.
#     """
# 
#     is_developer = models.BooleanField(default=False, blank=False)
#     accepted_tos = models.BooleanField(default=False, blank=False)
#     #  Add more custom fields here like avatar...
# 
#     def send_activation_email(self):
#         tvars = {
#             'user': self,
#             'username': self.username,
#             'hash': create_hash(self.id)
#         }
#         send_mail(self.email, subject='Activate your Audio Commons user account',
#                   template='emails/account_activation.txt', context=tvars)
# 
#     class Meta:
#         verbose_name = _('account')
#         verbose_name_plural = _('accounts')


from rest_framework.response import Response
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import AllowAny
from ac_mediator.exceptions import *
from api.request_distributor import get_request_distributor
from api.response_aggregator import get_response_aggregator
from services.mgmt import get_available_services
from services.acservice.constants import *
from django.conf import settings
from accounts.models import Account


request_distributor = get_request_distributor()
response_aggregator = get_response_aggregator()


def get_request_context(request):
    user_account_id = None
    dev_account_id = None
    if hasattr(request, 'successful_authenticator') and request.successful_authenticator:
        # In production API calls this should be always the case as otherwise API returns 401 before reaching here
        user_account_id = request.user.id
        dev_account_id = request.auth.application.user.id
    else:
        # In integration tests or local development it can happen that successful_authenticator does not exist
        # In that case we provide 'fake' context so tests can be carried out correctly
        if request.user.is_authenticated():
            user_account_id = request.user.id
            dev_account_id = user_account_id
        else:
            if settings.DEBUG and settings.ALLOW_UNAUTHENTICATED_API_REQUESTS_ON_DEBUG:

# Path: api/request_distributor.py
# def get_request_distributor():
#     return request_distributor
# 
# Path: api/response_aggregator.py
# def get_response_aggregator():
#     return response_aggregator
# 
# Path: services/mgmt.py
# def get_available_services(component=None, exclude=None, include=None):
#     """
#     Get all available services which implement a particular component (or all services if
#     'component' is None). Allows excluding particular services and restricting those from which to filter.
#     :param component: component (mixin) that should be implemented by returned services
#     :param exclude: exclude services passed through this parameter (should be a list of service names)
#     :param include: consider only services passed through this parameter (should be a list of service names)
#     :return: list of matching services (can be empty)
#     """
#     out_services = list()
#     for service in available_services:
#         if component is not None:
#             if component not in service.implemented_components:
#                 continue
#         if exclude is not None:
#             if service.name in exclude:
#                 continue
#         if include is not None:
#             if service.name not in include:
#                 continue
#         out_services.append(service)
#     return out_services
# 
# Path: accounts/models.py
# class Account(AbstractUser):
#     """
#     This is our custom 'User' model.
#     """
# 
#     is_developer = models.BooleanField(default=False, blank=False)
#     accepted_tos = models.BooleanField(default=False, blank=False)
#     #  Add more custom fields here like avatar...
# 
#     def send_activation_email(self):
#         tvars = {
#             'user': self,
#             'username': self.username,
#             'hash': create_hash(self.id)
#         }
#         send_mail(self.email, subject='Activate your Audio Commons user account',
#                   template='emails/account_activation.txt', context=tvars)
# 
#     class Meta:
#         verbose_name = _('account')
#         verbose_name_plural = _('accounts')


# Path: api/views.py
from rest_framework.response import Response
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import AllowAny
from ac_mediator.exceptions import *
from api.request_distributor import get_request_distributor
from api.response_aggregator import get_response_aggregator
from services.mgmt import get_available_services
from services.acservice.constants import *
from django.conf import settings
from accounts.models import Account



request_distributor = get_request_distributor()
response_aggregator = get_response_aggregator()


def get_request_context(request):
    user_account_id = None
    dev_account_id = None
    if hasattr(request, 'successful_authenticator') and request.successful_authenticator:
        # In production API calls this should be always the case as otherwise API returns 401 before reaching here
        user_account_id = request.user.id
        dev_account_id = request.auth.application.user.id
    else:
        # In integration tests or local development it can happen that successful_authenticator does not exist
        # In that case we provide 'fake' context so tests can be carried out correctly
        if request.user.is_authenticated():
            user_account_id = request.user.id
            dev_account_id = user_account_id
        else:
            if settings.DEBUG and settings.ALLOW_UNAUTHENTICATED_API_REQUESTS_ON_DEBUG:

                user_account_id = Account.objects.all()[0].id