from mtools.util.logevent import LogEvent
from mtools.util.pattern import json2pattern
import re
from base_filter import BaseFilter

def custom_parse_array(value):
    return list(set(value.split()))

class LogLineFilter(BaseFilter):
    """ 
    """
    filterArgs = [
        ('--component', {
            'action':'store', 
            'nargs':'*', 
            'choices': LogEvent.log_components,
            'metavar':'CM', 
            'help':'only output log lines with component CM (multiple values are allowed).'
        }),
        ('--level',     {
            'action':'store', 
            'nargs':'*', 
            'metavar':'LL', 
            'choices': LogEvent.log_levels, 
            'help':'only output log lines with loglevel LL (multiple values are allowed).'
        }),
        ('--namespace', {
            'action':'store', 
            'nargs':'*', 
            'metavar':'NS', 
            'help':'only output log lines on namespace NS (multiple values are allowed).'
        }),
        ('--operation', {
            'action':'store', 
            'nargs':'*', 
            'metavar':'OP', 
            'choices': LogEvent.log_operations, 
            'help':'only output log lines of type OP (multiple values are allowed).'
        }),
        ('--thread', {
            'nargs':'*', 
            'action':'store', 
            'help':'only output log lines of thread THREAD (multiple values are allowed).'
        }),
        ('--pattern', {
            'action':'store', 
            'help':'only output log lines with a query pattern PATTERN' \
                   ' (only applies to queries, getmores, updates, removes).'
        }),
        ('--command', {
            'nargs':'*', 
            'action':'store', 
            'help':'only output log lines which are commands of the given type. Examples: "distinct", "isMaster", "replSetGetStatus" (multiple values are allowed).'
        }),
        ('--planSummary', {
            'nargs':'*', 
            'metavar': 'PS',
            'action':'store', 
            'help':'only output log lines which match the given plan summary values (multiple values are allowed).'
        })
    ]

    def __init__(self, mlogfilter):
        BaseFilter.__init__(self, mlogfilter)

        self.components    = None
        self.levels        = None
        self.namespaces    = None
        self.operations    = None
        self.threads       = None
        self.commands      = None
        self.pattern       = None
        self.planSummaries = None

        if 'component' in self.mlogfilter.args and self.mlogfilter.args['component']:
            self.components = custom_parse_array(self.mlogfilter.args['component'])
            self.active = True
        if 'level' in self.mlogfilter.args and self.mlogfilter.args['level']:
            self.levels = custom_parse_array(self.mlogfilter.args['level'])
            self.active = True
        if 'namespace' in self.mlogfilter.args and self.mlogfilter.args['namespace']:
            self.namespaces = custom_parse_array(self.mlogfilter.args['namespace'])
            self.active = True
        if 'operation' in self.mlogfilter.args and self.mlogfilter.args['operation']:
            self.operations = custom_parse_array(self.mlogfilter.args['operation'])
            self.active = True
        if 'command' in self.mlogfilter.args and self.mlogfilter.args['command']:
            self.commands = custom_parse_array(self.mlogfilter.args['command'])
            self.active = True    
        if 'thread' in self.mlogfilter.args and self.mlogfilter.args['thread']:
            self.threads = custom_parse_array(self.mlogfilter.args['thread'])
            self.active = True
        if 'pattern' in self.mlogfilter.args and self.mlogfilter.args['pattern']:
            self.pattern = json2pattern(self.mlogfilter.args['pattern'])
            self.active = True
            if self.pattern is None:
                 raise SystemExit("ERROR: cannot parse pattern \"%s\" as a JSON string" % self.mlogfilter.args['pattern'])
        if 'planSummary' in self.mlogfilter.args and self.mlogfilter.args['planSummary']:
            self.planSummaries = custom_parse_array(self.mlogfilter.args['planSummary'])
            self.active = True

    def accept(self, logevent):
        # if several filters are active, all have to agree
        res = False
        if self.components and logevent.component not in self.components:
            return False
        if self.levels and logevent.level not in self.levels:
            return False
        if self.namespaces and logevent.namespace not in self.namespaces:
            return False
        if self.commands and logevent.command not in self.commands:
            return False
        if self.operations and logevent.operation not in self.operations:
            return False
        if self.threads:
            if logevent.thread not in self.threads and logevent.conn not in self.threads:
                return False
        if self.pattern and logevent.pattern != self.pattern:
            return False
        if self.planSummaries and logevent.planSummary not in self.planSummaries:
            return False
        
        return True

@@ -285,24 +285,50 @@
 mponent', %7B%0A
+            'nargs':'*', %0A
             
@@ -336,33 +336,32 @@
 action':'store',
- 
 %0A            'na
@@ -354,36 +354,41 @@
            '
-nargs':'*', 
+type': str.upper,
 %0A           
@@ -592,38 +592,33 @@
            '
-action':'store
+nargs':'*
 ', %0A        
@@ -618,36 +618,40 @@
            '
-nargs':'*
+action':'store
 ',
- 
 %0A           
@@ -851,38 +851,33 @@
            '
-action':'store
+nargs':'*
 ', %0A        
@@ -877,36 +877,40 @@
            '
-nargs':'*
+action':'store
 ',
- 
 %0A           
@@ -1064,38 +1064,33 @@
            '
-action':'store
+nargs':'*
 ', %0A        
@@ -1090,36 +1090,40 @@
            '
-nargs':'*
+action':'store
 ',
- 
 %0A           
@@ -1356,33 +1356,32 @@
 action':'store',
- 
 %0A            'he
@@ -1513,33 +1513,32 @@
 action':'store',
- 
 %0A            'he
@@ -1756,33 +1756,32 @@
 action':'store',
- 
 %0A            'he
@@ -2013,21 +2013,22 @@
    '
-metavar': 'PS
+action':'store
 ',%0A 
@@ -2043,25 +2043,54 @@
    '
-action':'store', 
+type': str.upper,%0A            'metavar': 'PS',
 %0A   

Fix #504: mlogfilter --component and --planSummary values should be case-insensitive (#505)