from typing import Optional, Any

from graphql import GraphQLResolveInfo

from core.get_value import get_value
from data.schemas.administration.user import User
from data.schemas.permission.permission import Permission
from service.permission.permissions_enum import Permissions


class QueryContext:

    def __init__(
        self,
        data: Any,
        user: Optional[User],
        user_permissions: Optional[list[Permissions]],
        is_mutation: bool = False,
        *args,
        **kwargs
    ):

        self._data = data
        self._user = user
        if user_permissions is None:
            user_permissions = []
        self._user_permissions: list[str] = [x.value for x in user_permissions]

        self._resolve_info = None
        for arg in args:
            if isinstance(arg, GraphQLResolveInfo):
                self._resolve_info = arg
                continue

        self._filter = kwargs.get("filters", {})
        self._sort = kwargs.get("sort", {})
        self._skip = get_value(kwargs, "skip", int)
        self._take = get_value(kwargs, "take", int)

        self._input = kwargs.get("input", None)
        self._args = args
        self._kwargs = kwargs

        self._is_mutation = is_mutation

    @property
    def data(self):
        return self._data

    @property
    def user(self) -> User:
        return self._user

    @property
    def resolve_info(self) -> Optional[GraphQLResolveInfo]:
        return self._resolve_info

    @property
    def filter(self) -> dict:
        return self._filter

    @property
    def sort(self) -> dict:
        return self._sort

    @property
    def skip(self) -> Optional[int]:
        return self._skip

    @property
    def take(self) -> Optional[int]:
        return self._take

    @property
    def input(self) -> Optional[Any]:
        return self._input

    @property
    def args(self) -> tuple:
        return self._args

    @property
    def kwargs(self) -> dict:
        return self._kwargs

    @property
    def is_mutation(self) -> bool:
        return self._is_mutation

    def has_permission(self, permission: Permissions) -> bool:
        return permission.value in self._user_permissions
