from __future__ import absolute_import

from vulture import Vulture
from vulture.core import ENCODING_REGEX
from vulture.utils import VultureInputException

from .base import PythonTool, Issue, ParseIssue, AccessIssue
from ..util import parse_python_file


class VultureIssue(Issue):
    tool = 'vulture'
    pylint_type = 'R'


class TidyPyVulture(Vulture):
    ISSUE_TYPES = (
        ('unused-class', 'Unused class {entity}', 'unused_classes'),
        ('unused-function', 'Unused function {entity}', 'unused_funcs'),
        ('unused-import', 'Unused import {entity}', 'unused_imports'),
        ('unused-property', 'Unused property {entity}', 'unused_props'),
        ('unused-variable', 'Unused variable {entity}', 'unused_vars'),
        ('unused-attribute', 'Unused attribute {entity}', 'unused_attrs')
    )

    def __init__(self, config):
        super(TidyPyVulture, self).__init__()
        self.config = config
        self._tidypy_issues = []

    def scavenge(self, finder):  # pylint: disable=arguments-differ
        self._tidypy_issues = []

        if self.config['options']['whitelist']:
            self.scan(
                '\n'.join(self.config['options']['whitelist']),
                filename='VultureWhitelist',
            )

        for filepath in finder.files(self.config['filters']):
            try:
                source = finder.read_file(filepath)
            except VultureInputException as exc:
                self._tidypy_issues.append(ParseIssue(exc, filepath))
                continue
            except EnvironmentError as exc:
                self._tidypy_issues.append(AccessIssue(exc, filepath))
                continue

            self.scan(source, filename=filepath)

    # Unfortunately instead of raising exceptions, this base implementation of
    # this method writes directly to stdout. This is a copy&paste with that
    # piece replaced by capturing an issue
    def scan(self, code, filename=''):
        code = ENCODING_REGEX.sub("", code, count=1)
        self.code = code.splitlines()
        self.filename = filename
        try:
            node = parse_python_file(self.filename)
        except (SyntaxError, TypeError) as err:
            self._tidypy_issues.append(ParseIssue(err, filename))
        else:
            self.visit(node)

    def get_issues(self):
        issues = []

        for code, template, prop_name in self.ISSUE_TYPES:
            if code in self.config['disabled']:
                continue

            for item in getattr(self, prop_name):
                try:
                    filename = item.file
                except AttributeError:
                    filename = item.filename

                issues.append(VultureIssue(
                    code,
                    template.format(entity=str(item)),
                    filename,
                    item.first_lineno,
                ))

        return self._tidypy_issues + issues


class VultureTool(PythonTool):
    """
    Vulture finds unused code in Python programs.
    """

    @classmethod
    def get_default_config(cls):
        config = PythonTool.get_default_config()
        config['options']['whitelist'] = []
        return config

    @classmethod
    def get_all_codes(cls):
        return [
            (code, tmpl)
            for code, tmpl, _ in TidyPyVulture.ISSUE_TYPES
        ]

    def __init__(self, *args, **kwargs):
        super(VultureTool, self).__init__(*args, **kwargs)
        self.vulture = TidyPyVulture(self.config)

    def execute(self, finder):
        self.vulture.scavenge(finder)
        return self.vulture.get_issues()


@@ -33,16 +33,45 @@
 import%0A%0A
+from six import string_types%0A
 from vul
@@ -90,16 +90,16 @@
 Vulture%0A
-
 from vul
@@ -884,44 +884,473 @@
     
-super(TidyPyVulture, self).__init__(
+ignore_names = config%5B'options'%5D%5B'ignore-names'%5D%0A        if isinstance(ignore_names, string_types):%0A            ignore_names = ignore_names.split(',')%0A%0A        ignore_decorators = config%5B'options'%5D%5B'ignore-decorators'%5D%0A        if isinstance(ignore_decorators, string_types):%0A            ignore_decorators = ignore_decorators.split(',')%0A%0A        super(TidyPyVulture, self).__init__(%0A            ignore_names=ignore_names, ignore_decorators=ignore_decorators%0A        
 )%0A  
@@ -2794,32 +2794,98 @@
      issues = %5B%5D
+%0A        min_confidence = self.config%5B'options'%5D%5B'min-confidence'%5D
 %0A%0A        for co
@@ -3049,24 +3049,107 @@
 prop_name):%0A
+                if item.confidence %3C min_confidence:%0A                    continue%0A%0A
             
@@ -3769,26 +3769,157 @@
 ns'%5D
-%5B'whitelist'%5D = %5B%5D
+ = %7B%0A            'ignore-names': None,%0A            'ignore-decorators': None,%0A            'min-confidence': 0,%0A            'whitelist': %5B%5D,%0A        %7D
 %0A   

Add support for vulture options