from __future__ import unicode_literals, division, absolute_import
from builtins import *  # noqa pylint: disable=unused-import, redefined-builtin

import logging

from flexget import plugin
from flexget.event import event
from flexget.utils.tools import aggregate_inputs

log = logging.getLogger('crossmatch')


class CrossMatch(object):
    """
    Perform action based on item on current task and other inputs.

    Example::

      crossmatch:
        from:
          - rss: http://example.com/
        fields:
          - title
        action: reject
        exact: yes
        case_sensitive: yes
    """

    schema = {
        'type': 'object',
        'properties': {
            'fields': {'type': 'array', 'items': {'type': 'string'}},
            'action': {'enum': ['accept', 'reject']},
            'from': {'type': 'array', 'items': {'$ref': '/schema/plugins?phase=input'}},
            'exact': {'type': 'boolean', 'default': True},
            'all_fields': {'type': 'boolean', 'default': False},
            'case_sensitive': {'type': 'boolean', 'default': True}
        },
        'required': ['fields', 'action', 'from'],
        'additionalProperties': False,
    }

    def on_task_filter(self, task, config):

        fields = config['fields']
        action = config['action']
        all_fields = config['all_fields']

        match_entries = aggregate_inputs(task, config['from'])

        # perform action on intersecting entries
        for entry in task.entries:
            for generated_entry in match_entries:
                log.trace('checking if %s matches %s', entry['title'], generated_entry['title'])
                common = self.entry_intersects(entry, generated_entry, fields, config.get('exact'), config.get('case_sensitive'))
                if common and (not all_fields or len(common) == len(fields)):
                    msg = 'intersects with %s on field(s) %s' % (
                        generated_entry['title'],
                        ', '.join(common),
                    )
                    for key in generated_entry:
                        if key not in entry:
                            entry[key] = generated_entry[key]
                    if action == 'reject':
                        entry.reject(msg)
                    if action == 'accept':
                        entry.accept(msg)

    def entry_intersects(self, e1, e2, fields=None, exact=True, case_sensitive=True):
        """
        :param e1: First :class:`flexget.entry.Entry`
        :param e2: Second :class:`flexget.entry.Entry`
        :param fields: List of fields which are checked
        :return: List of field names in common
        """

        if fields is None:
            fields = []

        common_fields = []

        for field in fields:
            # Doesn't really make sense to match if field is not in both entries
            if field not in e1 or field not in e2:
                log.trace('field %s is not in both entries', field)
                continue

            if case_sensitive:
                v1 = e1[field]
                v2 = e2[field]
            else:
                v1 = e1[field].lower()
                v2 = e2[field].lower()

            try:
                if v1 == v2 or not exact and (v2 in v1 or v1 in v2):
                    common_fields.append(field)
                else:
                    log.trace('not matching')
            except TypeError as e:
                # argument of type <type> is not iterable
                log.trace('error matching fields: %s', str(e))

        return common_fields


@event('plugin.register')
def register_plugin():
    plugin.register(CrossMatch, 'crossmatch', api_ver=2)

@@ -3020,16 +3020,20 @@
      if 
+not 
 case_sen
@@ -3038,16 +3038,47 @@
 ensitive
+ and isinstance(e1%5Bfield%5D, str)
 :%0A      
@@ -3097,31 +3097,51 @@
  = e1%5Bfield%5D
-%0A      
+.lower()%0A            else:%0A
           v2
@@ -3134,31 +3134,37 @@
 :%0A          
-v2
+      v1
  = e
-2
+1
 %5Bfield%5D%0A    
@@ -3163,36 +3163,84 @@
 ld%5D%0A            
-else
+if not case_sensitive and isinstance(e1%5Bfield%5D, str)
 :%0A              
@@ -3234,38 +3234,38 @@
                v
-1
+2
  = e
-1
+2
 %5Bfield%5D.lower()%0A
@@ -3256,32 +3256,50 @@
 %5Bfield%5D.lower()%0A
+            else:%0A
                 
@@ -3312,24 +3312,16 @@
 2%5Bfield%5D
-.lower()
 %0A%0A      

Add string validation