"""Testing `tabnanny` module.

Glossary:
    * errored    : Whitespace related problems present in file.
"""
from unittest import TestCase, mock
from unittest import mock
import errno
import os
import sys
import tabnanny
import tokenize
import tempfile
import textwrap
from test.support import (captured_stderr, captured_stdout, script_helper,
                          findfile, unlink)


SOURCE_CODES = {
    "incomplete_expression": (
        'fruits = [\n'
        '    "Apple",\n'
        '    "Orange",\n'
        '    "Banana",\n'
        '\n'
        'print(fruits)\n'
    ),
    "wrong_indented": (
        'if True:\n'
        '    print("hello")\n'
        '  print("world")\n'
        'else:\n'
        '    print("else called")\n'
    ),
    "nannynag_errored": (
        'if True:\n'
        ' \tprint("hello")\n'
        '\tprint("world")\n'
        'else:\n'
        '    print("else called")\n'
    ),
    "error_free": (
        'if True:\n'
        '    print("hello")\n'
        '    print("world")\n'
        'else:\n'
        '    print("else called")\n'
    ),
    "tab_space_errored_1": (
        'def my_func():\n'
        '\t  print("hello world")\n'
        '\t  if True:\n'
        '\t\tprint("If called")'
    ),
    "tab_space_errored_2": (
        'def my_func():\n'
        '\t\tprint("Hello world")\n'
        '\t\tif True:\n'
        '\t        print("If called")'
    )
}


class TemporaryPyFile:
    """Create a temporary python source code file."""

    def __init__(self, source_code='', directory=None):
        self.source_code = source_code
        self.dir = directory

    def __enter__(self):
        with tempfile.NamedTemporaryFile(
            mode='w', dir=self.dir, suffix=".py", delete=False
        ) as f:
            f.write(self.source_code)
        self.file_path = f.name
        return self.file_path

    def __exit__(self, exc_type, exc_value, exc_traceback):
        unlink(self.file_path)


class TestFormatWitnesses(TestCase):
    """Testing `tabnanny.format_witnesses()`."""

    def test_format_witnesses(self):
        """Asserting formatter result by giving various input samples."""
        tests = [
            ('Test', 'at tab sizes T, e, s, t'),
            ('', 'at tab size '),
            ('t', 'at tab size t'),
            ('  t  ', 'at tab sizes  ,  , t,  ,  '),
        ]

        for words, expected in tests:
            with self.subTest(words=words, expected=expected):
                self.assertEqual(tabnanny.format_witnesses(words), expected)


class TestErrPrint(TestCase):
    """Testing `tabnanny.errprint()`."""

    def test_errprint(self):
        """Asserting result of `tabnanny.errprint()` by giving sample inputs."""
        tests = [
            (['first', 'second'], 'first second\n'),
            (['first'], 'first\n'),
            ([1, 2, 3], '1 2 3\n'),
            ([], '\n')
        ]

        for args, expected in tests:
            with self.subTest(arguments=args, expected=expected):
                with captured_stderr() as stderr:
                    tabnanny.errprint(*args)
                self.assertEqual(stderr.getvalue() , expected)


class TestNannyNag(TestCase):
    def test_all_methods(self):
        """Asserting behaviour of `tabnanny.NannyNag` exception."""
        tests = [
            (
                tabnanny.NannyNag(0, "foo", "bar"),
                {'lineno': 0, 'msg': 'foo', 'line': 'bar'}
            ),
            (
                tabnanny.NannyNag(5, "testmsg", "testline"),
                {'lineno': 5, 'msg': 'testmsg', 'line': 'testline'}
            )
        ]
        for nanny, expected in tests:
            line_number = nanny.get_lineno()
            msg = nanny.get_msg()
            line = nanny.get_line()
            with self.subTest(
                line_number=line_number, expected=expected['lineno']
            ):
                self.assertEqual(expected['lineno'], line_number)
            with self.subTest(msg=msg, expected=expected['msg']):
                self.assertEqual(expected['msg'], msg)
            with self.subTest(line=line, expected=expected['line']):
                self.assertEqual(expected['line'], line)


class TestCheck(TestCase):
    """Testing tabnanny.check()."""

    def setUp(self):
        self.addCleanup(setattr, tabnanny, 'verbose', tabnanny.verbose)
        tabnanny.verbose = 0  # Forcefully deactivating verbose mode.

    def verify_tabnanny_check(self, dir_or_file, out="", err=""):
        """Common verification for tabnanny.check().

        Use this method to assert expected values of `stdout` and `stderr` after
        running tabnanny.check() on given `dir` or `file` path. Because
        tabnanny.check() captures exceptions and writes to `stdout` and
        `stderr`, asserting standard outputs is the only way.
        """
        with captured_stdout() as stdout, captured_stderr() as stderr:
            tabnanny.check(dir_or_file)
        self.assertEqual(stdout.getvalue(), out)
        self.assertEqual(stderr.getvalue(), err)

    def test_correct_file(self):
        """A python source code file without any errors."""
        with TemporaryPyFile(SOURCE_CODES["error_free"]) as file_path:
            self.verify_tabnanny_check(file_path)

    def test_correct_directory_verbose(self):
        """Directory containing few error free python source code files.

        Because order of files returned by `os.lsdir()` is not fixed, verify the
        existence of each output lines at `stdout` using `in` operator.
        `verbose` mode of `tabnanny.verbose` asserts `stdout`.
        """
        with tempfile.TemporaryDirectory() as tmp_dir:
            lines = [f"{tmp_dir!r}: listing directory\n",]
            file1 = TemporaryPyFile(SOURCE_CODES["error_free"], directory=tmp_dir)
            file2 = TemporaryPyFile(SOURCE_CODES["error_free"], directory=tmp_dir)
            with file1 as file1_path, file2 as file2_path:
                for file_path in (file1_path, file2_path):
                    lines.append(f"{file_path!r}: Clean bill of health.\n")

                tabnanny.verbose = 1
                with captured_stdout() as stdout, captured_stderr() as stderr:
                    tabnanny.check(tmp_dir)
                stdout = stdout.getvalue()
                for line in lines:
                    with self.subTest(line=line):
                        self.assertIn(line, stdout)
                self.assertEqual(stderr.getvalue(), "")

    def test_correct_directory(self):
        """Directory which contains few error free python source code files."""
        with tempfile.TemporaryDirectory() as tmp_dir:
            with TemporaryPyFile(SOURCE_CODES["error_free"], directory=tmp_dir):
                self.verify_tabnanny_check(tmp_dir)

    def test_when_wrong_indented(self):
        """A python source code file eligible for raising `IndentationError`."""
        with TemporaryPyFile(SOURCE_CODES["wrong_indented"]) as file_path:
            err = ('unindent does not match any outer indentation level'
                ' (<tokenize>, line 3)\n')
            err = f"{file_path!r}: Indentation Error: {err}"
            self.verify_tabnanny_check(file_path, err=err)

    def test_when_tokenize_tokenerror(self):
        """A python source code file eligible for raising 'tokenize.TokenError'."""
        with TemporaryPyFile(SOURCE_CODES["incomplete_expression"]) as file_path:
            err = "('EOF in multi-line statement', (7, 0))\n"
            err = f"{file_path!r}: Token Error: {err}"
            self.verify_tabnanny_check(file_path, err=err)

    def test_when_nannynag_error_verbose(self):
        """A python source code file eligible for raising `tabnanny.NannyNag`.

        Tests will assert `stdout` after activating `tabnanny.verbose` mode.
        """
        with TemporaryPyFile(SOURCE_CODES["nannynag_errored"]) as file_path:
            out = f"{file_path!r}: *** Line 3: trouble in tab city! ***\n"
            out += "offending line: '\\tprint(\"world\")\\n'\n"
            out += "indent not equal e.g. at tab size 1\n"

            tabnanny.verbose = 1
            self.verify_tabnanny_check(file_path, out=out)

    def test_when_nannynag_error(self):
        """A python source code file eligible for raising `tabnanny.NannyNag`."""
        with TemporaryPyFile(SOURCE_CODES["nannynag_errored"]) as file_path:
            out = f"{file_path} 3 '\\tprint(\"world\")\\n'\n"
            self.verify_tabnanny_check(file_path, out=out)

    def test_when_no_file(self):
        """A python file which does not exist actually in system."""
        path = 'no_file.py'
        err = (f"{path!r}: I/O Error: [Errno {errno.ENOENT}] "
              f"{os.strerror(errno.ENOENT)}: {path!r}\n")
        self.verify_tabnanny_check(path, err=err)

    def test_errored_directory(self):
        """Directory containing wrongly indented python source code files."""
        with tempfile.TemporaryDirectory() as tmp_dir:
            error_file = TemporaryPyFile(
                SOURCE_CODES["wrong_indented"], directory=tmp_dir
            )
            code_file = TemporaryPyFile(
                SOURCE_CODES["error_free"], directory=tmp_dir
            )
            with error_file as e_file, code_file as c_file:
                err = ('unindent does not match any outer indentation level'
                            ' (<tokenize>, line 3)\n')
                err = f"{e_file!r}: Indentation Error: {err}"
                self.verify_tabnanny_check(tmp_dir, err=err)


class TestProcessTokens(TestCase):
    """Testing `tabnanny.process_tokens()`."""

    @mock.patch('tabnanny.NannyNag')
    def test_with_correct_code(self, MockNannyNag):
        """A python source code without any whitespace related problems."""

        with TemporaryPyFile(SOURCE_CODES["error_free"]) as file_path:
            with open(file_path) as f:
                tabnanny.process_tokens(tokenize.generate_tokens(f.readline))
            self.assertFalse(MockNannyNag.called)

    def test_with_errored_codes_samples(self):
        """A python source code with whitespace related sampled problems."""

        # "tab_space_errored_1": executes block under type == tokenize.INDENT
        #                        at `tabnanny.process_tokens()`.
        # "tab space_errored_2": executes block under
        #                        `check_equal and type not in JUNK` condition at
        #                        `tabnanny.process_tokens()`.

        for key in ["tab_space_errored_1", "tab_space_errored_2"]:
            with self.subTest(key=key):
                with TemporaryPyFile(SOURCE_CODES[key]) as file_path:
                    with open(file_path) as f:
                        tokens = tokenize.generate_tokens(f.readline)
                        with self.assertRaises(tabnanny.NannyNag):
                            tabnanny.process_tokens(tokens)


class TestCommandLine(TestCase):
    """Tests command line interface of `tabnanny`."""

    def validate_cmd(self, *args, stdout="", stderr="", partial=False):
        """Common function to assert the behaviour of command line interface."""
        _, out, err = script_helper.assert_python_ok('-m', 'tabnanny', *args)
        # Note: The `splitlines()` will solve the problem of CRLF(\r) added
        # by OS Windows.
        out = out.decode('ascii')
        err = err.decode('ascii')
        if partial:
            for std, output in ((stdout, out), (stderr, err)):
                _output = output.splitlines()
                for _std in std.splitlines():
                    with self.subTest(std=_std, output=_output):
                        self.assertIn(_std, _output)
        else:
            self.assertListEqual(out.splitlines(), stdout.splitlines())
            self.assertListEqual(err.splitlines(), stderr.splitlines())

    def test_with_errored_file(self):
        """Should displays error when errored python file is given."""
        with TemporaryPyFile(SOURCE_CODES["wrong_indented"]) as file_path:
            stderr  = f"{file_path!r}: Indentation Error: "
            stderr += ('unindent does not match any outer indentation level'
                    ' (<tokenize>, line 3)')
            self.validate_cmd(file_path, stderr=stderr)

    def test_with_error_free_file(self):
        """Should not display anything if python file is correctly indented."""
        with TemporaryPyFile(SOURCE_CODES["error_free"]) as file_path:
            self.validate_cmd(file_path)

    def test_command_usage(self):
        """Should display usage on no arguments."""
        path = findfile('tabnanny.py')
        stderr = f"Usage: {path} [-v] file_or_directory ..."
        self.validate_cmd(stderr=stderr)

    def test_quiet_flag(self):
        """Should display less when quite mode is on."""
        with TemporaryPyFile(SOURCE_CODES["nannynag_errored"]) as file_path:
            stdout = f"{file_path}\n"
            self.validate_cmd("-q", file_path, stdout=stdout)

    def test_verbose_mode(self):
        """Should display more error information if verbose mode is on."""
        with TemporaryPyFile(SOURCE_CODES["nannynag_errored"]) as path:
            stdout = textwrap.dedent(
                "offending line: '\\tprint(\"world\")\\n'"
            ).strip()
            self.validate_cmd("-v", path, stdout=stdout, partial=True)

    def test_double_verbose_mode(self):
        """Should display detailed error information if double verbose is on."""
        with TemporaryPyFile(SOURCE_CODES["nannynag_errored"]) as path:
            stdout = textwrap.dedent(
                "offending line: '\\tprint(\"world\")\\n'"
            ).strip()
            self.validate_cmd("-vv", path, stdout=stdout, partial=True)
