"""
Test option and argument definitions in parsed script commands
"""


import sys
import os
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *


class ParsedCommandTestCase(TestBase):
    NO_DEBUG_INFO_TESTCASE = True

    def test(self):
        self.pycmd_tests()

    def setUp(self):
        TestBase.setUp(self)
        self.stdin_path = self.getBuildArtifact("stdin.txt")
        self.stdout_path = self.getBuildArtifact("stdout.txt")

    def check_help_options(self, cmd_name, opt_list, substrs=[]):
        """
        Pass the command name in cmd_name and a vector of the short option, type & long option.
        This will append the checks for all the options and test "help command".
        Any strings already in substrs will also be checked.
        Any element in opt list that begin with "+" will be added to the checked strings as is.
        """
        for elem in opt_list:
            if elem[0] == "+":
                substrs.append(elem[1:])
            else:
                (short_opt, type, long_opt) = elem
                substrs.append(f"-{short_opt} <{type}> ( --{long_opt} <{type}> )")
        self.expect("help " + cmd_name, substrs=substrs)

    def run_one_repeat(self, commands, expected_num_errors):
        with open(self.stdin_path, "w") as input_handle:
            input_handle.write(commands)

        in_fileH = open(self.stdin_path, "r")
        self.dbg.SetInputFileHandle(in_fileH, False)

        out_fileH = open(self.stdout_path, "w")
        self.dbg.SetOutputFileHandle(out_fileH, False)
        self.dbg.SetErrorFileHandle(out_fileH, False)

        options = lldb.SBCommandInterpreterRunOptions()
        options.SetEchoCommands(False)
        options.SetPrintResults(True)
        options.SetPrintErrors(True)
        options.SetAllowRepeats(True)

        n_errors, quit_requested, has_crashed = self.dbg.RunCommandInterpreter(
            True, False, options, 0, False, False
        )

        in_fileH.close()
        out_fileH.close()

        results = None
        with open(self.stdout_path, "r") as out_fileH:
            results = out_fileH.read()

        self.assertEqual(n_errors, expected_num_errors)

        return results

    def handle_completion(
        self,
        cmd_str,
        exp_num_completions,
        exp_matches,
        exp_descriptions,
        match_description,
    ):
        matches = lldb.SBStringList()
        descriptions = lldb.SBStringList()

        interp = self.dbg.GetCommandInterpreter()
        num_completions = interp.HandleCompletionWithDescriptions(
            cmd_str, len(cmd_str), 0, 1000, matches, descriptions
        )
        self.assertEqual(
            num_completions, exp_num_completions, "Number of completions is right."
        )
        num_matches = matches.GetSize()
        self.assertEqual(
            num_matches,
            exp_matches.GetSize(),
            "matches and expected matches of different lengths",
        )
        num_descriptions = descriptions.GetSize()
        if match_description:
            self.assertEqual(
                num_descriptions,
                exp_descriptions.GetSize(),
                "descriptions and expected of different lengths",
            )

        self.assertEqual(
            matches.GetSize(),
            num_completions + 1,
            "The first element is the complete additional text",
        )

        for idx in range(0, num_matches):
            match = matches.GetStringAtIndex(idx)
            exp_match = exp_matches.GetStringAtIndex(idx)
            self.assertEqual(
                match, exp_match, f"{match} did not match expectation: {exp_match}"
            )
        if match_description:
            desc = descriptions.GetStringAtIndex(idx)
            exp_desc = exp_descriptions.GetStringAtIndex(idx)
            self.assertEqual(
                desc, exp_desc, f"{desc} didn't match expectation: {exp_desc}"
            )

    def pycmd_tests(self):
        source_dir = self.getSourceDir()
        test_file_path = os.path.join(source_dir, "test_commands.py")
        self.runCmd("command script import " + test_file_path)
        self.expect("help", substrs=["no-args", "one-arg-no-opt", "two-args"])

        # Test that we did indeed add these commands as user commands:

        # This is the function to remove the custom commands in order to have a
        # clean slate for the next test case.
        def cleanup():
            self.runCmd(
                "command script delete no-args one-arg-no-opt two-args", check=False
            )

        # Execute the cleanup function during test case tear down.
        self.addTearDownHook(cleanup)

        # First test the no arguments command.  Make sure the help is right:
        no_arg_opts = [
            ["b", "boolean", "bool-arg"],
            "+a boolean arg, defaults to True",
            ["d", "filename", "disk-file-name"],
            "+An on disk filename",
            ["e", "none", "enum-option"],
            "+An enum, doesn't actually do anything",
            "+Values: foo | bar | baz",
            ["l", "linenum", "line-num"],
            "+A line number",
            ["s", "shlib-name", "shlib-name"],
            "+A shared library name",
        ]
        substrs = [
            "Example command for use in debugging",
            "Syntax: no-args <cmd-options>",
        ]

        self.check_help_options("no-args", no_arg_opts, substrs)

        # Make sure the command doesn't accept arguments:
        self.expect(
            "no-args an-arg",
            substrs=["'no-args' doesn't take any arguments."],
            error=True,
        )

        # Try setting the bool with the wrong value:
        self.expect(
            "no-args -b Something",
            substrs=["Error setting option: bool-arg to Something"],
            error=True,
        )
        # Try setting the enum to an illegal value as well:
        self.expect(
            "no-args --enum-option Something",
            substrs=["error: Error setting option: enum-option to Something"],
            error=True,
        )

        # Check some of the command groups:
        self.expect(
            "no-args -b true -s Something -l 10",
            substrs=["error: invalid combination of options for the given command"],
            error=True,
        )

        # Now set the bool arg correctly, note only the first option was set:
        self.expect(
            "no-args -b true",
            substrs=[
                "bool-arg (set: True): True",
                "shlib-name (set: False):",
                "disk-file-name (set: False):",
                "line-num (set: False):",
                "enum-option (set: False):",
            ],
        )

        # Now set the enum arg correctly, note only the first option was set:
        self.expect(
            "no-args -e foo",
            substrs=[
                "bool-arg (set: False):",
                "shlib-name (set: False):",
                "disk-file-name (set: False):",
                "line-num (set: False):",
                "enum-option (set: True): foo",
            ],
        )
        # Try a pair together:
        self.expect(
            "no-args -b false -s Something",
            substrs=[
                "bool-arg (set: True): False",
                "shlib-name (set: True): Something",
                "disk-file-name (set: False):",
                "line-num (set: False):",
                "enum-option (set: False):",
            ],
        )

        # Next try some completion tests:

        interp = self.dbg.GetCommandInterpreter()
        matches = lldb.SBStringList()
        descriptions = lldb.SBStringList()

        # First try an enum completion:
        # Note - this is an enum so all the values are returned:
        matches.AppendList(["oo ", "foo"], 2)

        self.handle_completion("no-args -e f", 1, matches, descriptions, False)

        # Now try an internal completer, the on disk file one is handy:
        partial_name = os.path.join(source_dir, "test_")
        cmd_str = f"no-args -d '{partial_name}'"

        matches.Clear()
        descriptions.Clear()
        matches.AppendList(["commands.py' ", test_file_path], 2)
        # We don't have descriptions for the file path completer:
        self.handle_completion(cmd_str, 1, matches, descriptions, False)

        # Try a command with arguments.
        # FIXME: It should be enough to define an argument and it's type to get the completer
        # wired up for that argument type if it is a known type. But that isn't wired up in the
        # command parser yet, so I don't have any tests for that.  We also don't currently check
        # that the arguments passed match the argument specifications, so here I just pass a couple
        # sets of arguments and make sure we get back what we put in:
        self.expect(
            "two-args 'First Argument' 'Second Argument'",
            substrs=["0: First Argument", "1: Second Argument"],
        )

        # Now test custom completions - two-args has both option and arg completers.  In both
        # completers we return different values if the -p option is set, so we can test that too:
        matches.Clear()
        descriptions.Clear()
        cmd_str = "two-args -p something -c other_"
        matches.AppendString("something ")
        matches.AppendString("other_something")
        # This is a full match so no descriptions:
        self.handle_completion(cmd_str, 1, matches, descriptions, False)

        matches.Clear()
        descriptions.Clear()
        cmd_str = "two-args -c other_"
        matches.AppendList(["", "other_nice", "other_not_nice", "other_mediocre"], 4)
        # The option doesn't return descriptions either:
        self.handle_completion(cmd_str, 3, matches, descriptions, False)

        # Now try the argument - it says "no completions" if the proc_name was set:
        matches.Clear()
        descriptions.Clear()
        cmd_str = "two-args -p something arg"
        matches.AppendString("")
        self.handle_completion(cmd_str, 0, matches, descriptions, False)

        cmd_str = "two-args arg_"
        matches.Clear()
        descriptions.Clear()
        matches.AppendList(["", "arg_cool", "arg_yuck"], 3)
        descriptions.AppendList(["", "good idea", "bad idea"], 3)
        self.handle_completion(cmd_str, 2, matches, descriptions, True)

        # This one gets a single unique match:
        cmd_str = "two-args correct_"
        matches.Clear()
        descriptions.Clear()
        matches.AppendList(["answer ", "correct_answer"], 2)
        self.handle_completion(cmd_str, 1, matches, descriptions, False)

        # Now make sure get_repeat_command works properly:

        # no-args turns off auto-repeat
        results = self.run_one_repeat("no-args\n\n", 1)
        self.assertIn("No auto repeat", results, "Got auto-repeat error")

        # one-args does the normal repeat
        results = self.run_one_repeat("one-arg-no-opt ONE_ARG\n\n", 0)
        self.assertEqual(results.count("ONE_ARG"), 2, "We did a normal repeat")

        # two-args adds an argument:
        results = self.run_one_repeat("two-args FIRST_ARG SECOND_ARG\n\n", 0)
        self.assertEqual(
            results.count("FIRST_ARG"), 2, "Passed first arg to both commands"
        )
        self.assertEqual(
            results.count("SECOND_ARG"), 2, "Passed second arg to both commands"
        )
        self.assertEqual(results.count("THIRD_ARG"), 1, "Passed third arg in repeat")
