from api.route import Route
from api_graphql.abc.mutation_abc import MutationABC
from api_graphql.field.mutation_field_builder import MutationFieldBuilder
from api_graphql.service.exceptions import UnauthorizedException, AccessDenied
from core.logger import APILogger
from service.data_privacy_service import DataPrivacyService
from service.permission.permissions_enum import Permissions

logger = APILogger(__name__)


class PrivacyMutation(MutationABC):
    def __init__(self):
        MutationABC.__init__(self, "Privacy")

        self.field(
            MutationFieldBuilder("exportData")
            .with_resolver(self.resolve_export_data)
            .with_input(int, "userId")
            .with_public(True)
        )
        self.field(
            MutationFieldBuilder("anonymizeData")
            .with_resolver(self.resolve_anonymize_data)
            .with_input(int, "userId")
            .with_public(True)
        )
        self.field(
            MutationFieldBuilder("deleteData")
            .with_resolver(self.resolve_delete_data)
            .with_input(int, "userId")
            .with_public(True)
        )

    @staticmethod
    async def _permission_check(user_id: int):
        user = await Route.get_user()
        if user is None:
            raise UnauthorizedException()

        if user.id != user_id and not user.has_permission(Permissions.administrator):
            raise AccessDenied()

    @staticmethod
    async def resolve_export_data(user_id: int, *_):
        logger.debug(f"export data for user: {user_id}")
        await PrivacyMutation._permission_check(user_id)

        return await DataPrivacyService.export_user_data(user_id)

    @staticmethod
    async def resolve_anonymize_data(user_id: int, *_):
        logger.debug(f"anonymize data for user: {user_id}")
        await PrivacyMutation._permission_check(user_id)

        return await DataPrivacyService.anonymize_user(user_id)

    @staticmethod
    async def resolve_delete_data(user_id: int, *_):
        logger.debug(f"delete data for user: {user_id}")
        await PrivacyMutation._permission_check(user_id)

        return await DataPrivacyService.delete_user_data(user_id)
