import re
from typing import Union

from cruisecontrolclient.client.CCParameter.Parameter import AbstractParameter


class AbstractRegularExpressionParameter(AbstractParameter):
    def __init__(self, value: Union[str, re.Pattern]):
        AbstractParameter.__init__(self, value)

    def validate_value(self):
        if type(self.value) == re.Pattern:
            # If we've been passed a re.Pattern, obtain the string that comprised
            # this re.Pattern, and store that string as our value.
            #
            # This allows us to store a value that is the closest to what
            # cruise-control expects.
            self.value = self.value.pattern
        elif type(self.value) == str:
            # A string is not necessarily a regular expression; verify whether
            # it compiles into one.
            try:
                re.compile(self.value)
            except re.error as e:
                raise ValueError(f"{self.value} is not a valid regular expression", e)
        else:
            raise ValueError(f"{self.value} must be either a string or a re.Pattern")


class ExcludedTopicsParameter(AbstractRegularExpressionParameter):
    """excluded_topics=[pattern]"""
    name = 'excluded_topics'
    description = 'A regular expression matching which topics to exclude from this endpoint\'s action'
    argparse_properties = {
        'args': ('--excluded-topics', '--exclude-topics', '--exclude-topic'),
        'kwargs': dict(help=description, metavar='REGEX')
    }


class TopicParameter(AbstractRegularExpressionParameter):
    """topic=[topic]"""
    name = 'topic'
    description = 'A regular expression matching the desired topics'
    argparse_properties = {
        'args': ('--topic',),
        'kwargs': dict(help=description, metavar='REGEX')
    }
