from .grpc.blog_pb2 import (
    AddCommentRequest,
    AuthorBlogsRequest,
    BlogListRequest,
    BlogRetrieveCommentsRequest,
    BlogRetrieveRatesRequest,
    BlogRetrieveRequest,
    CategoryListRequest,
    CategoryRetrieveRequest,
    RateRequest,
)
from .grpc.blog_pb2_grpc import BlogControllerStub, CategoryControllerStub

SUCCESS_CODE = "0"


def _singletonize_class_vars(cls):
    for attr_name, attr_value in cls.__dict__.items():
        if isinstance(attr_value, type):  # it's a class
            orig_cls = attr_value

            class SingletonWrapper(orig_cls):
                _instances = {}

                def __new__(cls, *args, **kwargs):
                    if cls not in cls._instances:
                        cls._instances[cls] = super().__new__(cls)
                    return cls._instances[cls]

            setattr(cls, attr_name, SingletonWrapper)
    return cls


class RequestMessages:
    COMMENT = AddCommentRequest
    FETCH_AUTHOR_BLOGS = AuthorBlogsRequest
    FETCH_ALL_BLOG = BlogListRequest
    FETCH_ALL_CATEGORY = CategoryListRequest
    FETCH_BLOG = BlogRetrieveRequest
    FETCH_BLOG_COMMENTS = BlogRetrieveCommentsRequest
    FETCH_BLOG_RATES = BlogRetrieveRatesRequest
    FETCH_CATEGORY = CategoryRetrieveRequest
    RATE = RateRequest


class RPCMethodNames:
    COMMENT = "Comment"
    FETCH_AUTHOR_BLOGS = "FetchAuthorBlogs"
    FETCH_ONE = "Retrieve"
    FETCH_ALL = "List"
    FETCH_COMMENTS = "RetrieveComments"
    FETCH_RATES = "RetrieveRates"
    RATE = "Rate"


@_singletonize_class_vars
class Stubs:
    BLOG = BlogControllerStub
    CATEGORY = CategoryControllerStub


class InvokerUnits:
    PLACETAG_SITEMAP = "placetag_sitemap"
    SEARCH = "search"
