# coding: utf-8


import logging

from idm.api.exceptions import BadRequest
from idm.api.frontend.base import FrontendApiResource
from idm.api.frontend.group import GroupResource
from idm.api.frontend.forms import GroupChangedRolesForm
from idm.api.frontend.role import RoleResource

log = logging.getLogger(__name__)


class GroupChangedRolesResource(FrontendApiResource):
    class Meta(FrontendApiResource.Meta):
        abstract = False
        object_class = None
        resource_name = 'group_changed_roles'
        list_allowed_methods = ['get']
        detail_allowed_methods = []

    def get_list(self, request, **kwargs):
        form = GroupChangedRolesForm(request.GET.copy())
        if not form.is_valid():
            raise BadRequest(form.errors)

        group = form.cleaned_data.get('group')
        parent = form.cleaned_data.get('parent')
        membership_inheritance = form.cleaned_data.get('membership_inheritance')

        if membership_inheritance is not None and membership_inheritance == group.get_service().membership_inheritance:
            raise BadRequest('Nothing changes')
        elif parent is not None:
            if parent.type != group.type:
                raise BadRequest('Group and parent should have the same type')
            old_parent = group.get_tree_parent()
            if parent == old_parent:
                raise BadRequest('Nothing changes')
            descendants = group.get_unordered_tree_descendants(include_self=True)
            if parent in descendants:
                raise BadRequest('Descendant cannot be a new parent')

        result = group.get_changed_roles_for_new_root(
            new_root=parent,
            membership_inheritance=membership_inheritance
        )
        response = self.create_response(
            request=request,
            data=self.dehydrate(result),
        )
        return response

    def dehydrate(self, bundle):
        result = []
        group_resource = GroupResource()
        role_resource = RoleResource()
        for group, table in bundle.items():
            result.append({
                'group': group_resource.full_dehydrate(group_resource.build_bundle(obj=group), for_list=True).data,
                'obtained': [
                    role_resource.full_dehydrate(role_resource.build_bundle(obj=role), for_list=True).data
                    for role in table['obtained']
                ],
                'lost': [
                    role_resource.full_dehydrate(role_resource.build_bundle(obj=role), for_list=True).data
                    for role in table['lost']
                ],
            })

        return result
