# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.

"""
Tests for L{twistedchecker.core.runner}.
"""

import sys
import os
import operator

from functools import reduce

from pylint.reporters.text import TextReporter

from io import StringIO

from twisted.trial import unittest

import twistedchecker
from twistedchecker.core.runner import Runner
from twistedchecker.checkers.header import HeaderChecker

from twistedchecker.test.test_exceptionfinder import (
    createTestFiles as createTestFilesForFindingExceptions)



class RunnerTestCase(unittest.TestCase):
    """
    Test for twistedchecker.core.runner.Runner.
    """
    debug = False

    def setUp(self):
        """
        Redirect stdout to a temp C{StringIO} stream.
        """
        self.outputStream = StringIO()
        self.patch(sys, "stdout", self.outputStream)
        self.errorStream = StringIO()
        self.patch(sys, "stderr", self.errorStream)


    def clearOutputStream(self):
        """
        A function to clear output stream.
        """
        self.outputStream = StringIO()


    def makeRunner(self):
        """
        Return a runner instance.
        """
        runner = Runner()
        runner.setOutput(self.outputStream)
        return runner


    def _loadAllowedMessages(self):
        """
        Load allowed messages from test files.
        """
        pathTests = os.path.join(twistedchecker.abspath, "functionaltests")
        testfiles = reduce(operator.add,
                           [[os.path.join(pathDir, f) for f in files if f.endswith(".py")]
                            for pathDir, _, files in os.walk(pathTests)])
        messagesAllowed = set(Runner.allowedMessagesFromPylint)
        for testfile in testfiles:
            with open(testfile) as f:
                firstline = f.readline().strip()
            if (firstline.startswith("#") and "enable" in firstline
                                          and ":" in firstline):
                messages = firstline.split(":")[1].strip().split(",")
                messagesAllowed.update(messages)
        return messagesAllowed


    def test_findUselessCheckers(self):
        """
        Test for method findUselessCheckers
        """
        runner = Runner()
        registeredCheckers = sum(list(runner.linter._checkers.values()), [])
        # remove checkers other than header checker
        headerCheckerList = [ckr
                             for ckr in registeredCheckers
                             if type(ckr) == HeaderChecker]
        self.assertTrue(headerCheckerList)
        headerChecker = headerCheckerList[0]
        uselessCheckers = runner.findUselessCheckers(