from .grpc.invoice_pb2 import (
    CreateInvoiceRequest,
    InquiryInvoiceRetrieveRequest,
    InquiryPaymentRetrieveRequest,
    PaymentRequest,
    UserListInvoiceRequest,
    VerifyPaymentRequest,
)
from .grpc.invoice_pb2_grpc import (
    CreateInvoiceControllerStub,
    InquiryInvoiceControllerStub,
    InquiryPaymentControllerStub,
    PaymentInvoiceControllerStub,
    UserListInvoiceControllerStub,
)

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 InvoiceRequestMessages:
    CREATE = CreateInvoiceRequest
    INQUIRY = InquiryInvoiceRetrieveRequest
    FETCH_USER_INVOICES = UserListInvoiceRequest


class PaymentRequestMessages:
    REQUEST = PaymentRequest
    VERIFY = VerifyPaymentRequest
    INQUIRY = InquiryPaymentRetrieveRequest


class InvoiceRPCMethodNames:
    CREATE = "Create"
    INQUIRY = "Retrieve"
    FETCH_USER_INSTANCES = "UserRelatedList"


class PaymentRPCMethodNames:
    LIST_GATEWAYS = "ListGateways"
    REQUEST = "RequestPayment"
    VERIFY = "VerifyPayment"
    INQUIRY = "Retrieve"


@_singletonize_class_vars
class InvoiceStubs:
    CREATE = CreateInvoiceControllerStub
    INQUIRY = InquiryInvoiceControllerStub
    FETCH_USER_INVOICES = UserListInvoiceControllerStub


@_singletonize_class_vars
class PaymentStubs:
    INVOICE = PaymentInvoiceControllerStub
    INQUIRY = InquiryPaymentControllerStub
