from enum import auto
from typing import Optional, Union
from .data import DataObject, SameMimeType
from abc import ABC

from .root import EnumAutoName


class Status(EnumAutoName):
    """
    The standard permissions that apply to all HEA desktop objects.
    """
    COMPLETE = auto()  # No access to the object unless dynamic_permission() returns a non-None value.
    FAILED = auto()
    IN_PROGRESS = auto()


class Activity(DataObject, ABC):
    """
       Abstract base class for user activities.
       """
    pass


class UserActivity(Activity, SameMimeType):
    """
        Represents an user activity in the HEA desktop. Contains functions that allow access and setting of the value.

        activity_id (str)             : 123456
        user_id     (str)             : 123456
        action      (str)             : update
        status      (str)             : FAILED
        arn         (str)             : my_bucket
        """

    def __init__(self):
        super().__init__()
        self.__user_id: Optional[str] = None
        self.__action: Optional[str] = None
        self.__status: Optional[Union[Status, str]] = None
        self.__arn: Optional[str] = None

    @classmethod
    def get_mime_type(cls) -> str:
        return 'application/x.activity'

    @property
    def mime_type(self) -> str:
        return type(self).get_mime_type()

    @property
    def user_id(self) -> Optional[str]:
        """Returns the numerical user identifier"""
        return self.__user_id

    @user_id.setter
    def user_id(self, __user_id: Optional[str]) -> None:
        """Sets the numerical user identifier"""
        self.__user_id = str(__user_id) if __user_id is not None else None

    @property
    def action(self) -> Optional[str]:
        """Returns the string describes user action"""
        return self.__action

    @action.setter
    def action(self, __action: Optional[str]) -> None:
        """Sets the string describes user action"""
        self.__action = str(__action) if __action is not None else None

    @property
    def status(self) -> Optional[Union[Status, str]]:
        """Returns the string describes actions status"""
        return self.__status

    @status.setter
    def status(self, __status: Optional[Union[Status, str]]) -> None:
        """Sets the string describes actions status"""
        try:
            if isinstance(__status, Status):
                self.__status = __status
            elif isinstance(__status, str):
                self.__status = Status(__status)
            elif __status is None:
                self.__status = __status
            else:
                raise Exception()
        except Exception as e:
            raise KeyError(
                "Status can only be a Status object or string that can be converted to Status object")

    @property
    def arn(self) -> Optional[str]:
        """Returns the AWS resource identifier"""
        return self.__arn

    @arn.setter
    def arn(self, __arn: Optional[str]) -> None:
        """Sets the AWS resource identifier"""
        self.__arn = str(__arn) if __arn is not None else None
