#!/usr/bin/env python3
# Copyright 2016 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Unittests for the shell module."""

import difflib
from pathlib import Path
import sys
import unittest


THIS_FILE = Path(__file__).resolve()
THIS_DIR = THIS_FILE.parent
sys.path.insert(0, str(THIS_DIR.parent))

# We have to import our local modules after the sys.path tweak.  We can't use
# relative imports because this is an executable program, not a module.
# pylint: disable=wrong-import-position
import rh.shell


class DiffTestCase(unittest.TestCase):
    """Helper that includes diff output when failing."""

    def setUp(self):
        self.differ = difflib.Differ()

    def _assertEqual(self, func, test_input, test_output, result):
        """Like assertEqual but with built in diff support."""
        diff = "\n".join(list(self.differ.compare([test_output], [result])))
        msg = (
            f"Expected {func} to translate {test_input!r} to "
            f"{test_output!r}, but got {result!r}\n{diff}"
        )
        self.assertEqual(test_output, result, msg)

    def _testData(self, functor, tests, check_type=True):
        """Process a dict of test data."""
        for test_output, test_input in tests.items():
            result = functor(test_input)
            self._assertEqual(functor.__name__, test_input, test_output, result)

            if check_type:
                # Also make sure the result is a string, otherwise the %r
                # output will include a "u" prefix and that is not good for
                # logging.
                self.assertEqual(type(test_output), str)


class ShellQuoteTest(DiffTestCase):
    """Test the quote & unquote functions."""

    def testShellQuote(self):
        """Basic ShellQuote tests."""
        # Dict of expected output strings to input lists.
        tests_quote = {
            "''": "",
            "a": "a",
            "'a b c'": "a b c",
            "'a\tb'": "a\tb",
            "'/a$file'": "/a$file",
            "'/a#file'": "/a#file",
            """'b"c'""": 'b"c',
            "'a@()b'": "a@()b",
            "j%k": "j%k",
            r'''"s'a\$va\\rs"''': r"s'a$va\rs",
            r'''"\\'\\\""''': r'''\'\"''',
            r'''"'\\\$"''': r"""'\$""",
        }

        # Expected input output specific to ShellUnquote.  This string cannot
        # be produced by ShellQuote but is still a valid bash escaped string.
        tests_unquote = {
            r"""\$""": r'''"\\$"''',
        }

        def aux(s):
            return rh.shell.unquote(rh.shell.quote(s))

        self._testData(rh.shell.quote, tests_quote)
        self._testData(rh.shell.unquote, tests_unquote)

        # Test that the operations are reversible.
        self._testData(aux, {k: k for k in tests_quote.values()}, False)
        self._testData(aux, {k: k for k in tests_quote}, False)

    def testPathlib(self):
        """Verify pathlib is handled."""
        self.assertEqual(rh.shell.quote(Path("/")), "/")

    def testBadInputs(self):
        """Verify bad inputs do not crash."""
        for arg, exp in (
            (1234, "1234"),
            (Exception("hi"), "Exception('hi')"),
        ):
            self.assertEqual(rh.shell.quote(arg), exp)


class CmdToStrTest(DiffTestCase):
    """Test the cmd_to_str function."""

    def testCmdToStr(self):
        # Dict of expected output strings to input lists.
        tests = {
            r"a b": ["a", "b"],
            r"'a b' c": ["a b", "c"],
            r'''a "b'c"''': ["a", "b'c"],
            r'''a "/'\$b" 'a b c' "xy'z"''': ["a", "/'$b", "a b c", "xy'z"],
            "": [],
        }
        self._testData(rh.shell.cmd_to_str, tests)


class BooleanShellTest(unittest.TestCase):
    """Test the boolean_shell_value function."""

    def testFull(self):
        """Verify nputs work as expected"""
        for v in (None,):
            self.assertTrue(rh.shell.boolean_shell_value(v, True))
            self.assertFalse(rh.shell.boolean_shell_value(v, False))

        for v in (1234, "", "akldjsf", '"'):
            self.assertRaises(ValueError, rh.shell.boolean_shell_value, v, True)

        for v in (
            "yes",
            "YES",
            "YeS",
            "y",
            "Y",
            "1",
            "true",
            "True",
            "TRUE",
        ):
            self.assertTrue(rh.shell.boolean_shell_value(v, True))
            self.assertTrue(rh.shell.boolean_shell_value(v, False))

        for v in (
            "no",
            "NO",
            "nO",
            "n",
            "N",
            "0",
            "false",
            "False",
            "FALSE",
        ):
            self.assertFalse(rh.shell.boolean_shell_value(v, True))
            self.assertFalse(rh.shell.boolean_shell_value(v, False))


if __name__ == "__main__":
    unittest.main()
