import grpc
from enum import Enum
from common.exceptions.ServiceException import ServiceException

def check_enum(enum_name, method_name, value, to_enum_method, accepted_values_dict) -> Enum:
    _value = to_enum_method(value)
    if _value is None:                          # pragma: no cover (gRPC prevents unsupported values)
        msg = 'Unsupported {}({}).'
        msg = msg.format(enum_name, value)
        raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, msg)

    accepted_values = accepted_values_dict.get(method_name)
    if accepted_values is None:                 # pragma: no cover (test requires malforming the code)
        msg = '{} acceptable values not specified for Method({}).'
        msg = msg.format(enum_name, method_name)
        raise ServiceException(grpc.StatusCode.INTERNAL, msg)

    if len(accepted_values) == 0: return _value
    if _value in accepted_values: return _value

    msg = 'Method({}) does not accept {}({}). Permitted values for Method({}) are {}({}).'
    accepted_values_list = sorted(map(lambda v: v.name, accepted_values))
    msg = msg.format(method_name, enum_name, _value.name, method_name, enum_name, accepted_values_list)
    raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, msg)
