"""
Test that the lldb-mi driver understands MI command syntax.
"""

from __future__ import print_function


import lldbmi_testcase
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
from functools import reduce


class MiSyntaxTestCase(lldbmi_testcase.MiTestCaseBase):

    mydir = TestBase.compute_mydir(__file__)

    @skipIfWindows  # llvm.org/pr24452: Get lldb-mi tests working on Windows
    @skipIfFreeBSD  # llvm.org/pr22411: Failure presumably due to known thread races
    @skipIfRemote   # We do not currently support remote debugging via the MI.
    @skipIfDarwin
    def test_lldbmi_tokens(self):
        """Test that 'lldb-mi --interpreter' prints command tokens."""

        self.spawnLldbMi(args=None)

        # Load executable
        self.runCmd("000-file-exec-and-symbols %s" % self.myexe)
        self.expect("000\^done")

        # Run to main
        self.runCmd("100000001-break-insert -f main")
        self.expect("100000001\^done,bkpt={number=\"1\"")
        self.runCmd("2-exec-run")
        self.expect("2\^running")
        self.expect("\*stopped,reason=\"breakpoint-hit\"")

        # Exit
        self.runCmd("0000000000000000000003-exec-continue")
        self.expect("0000000000000000000003\^running")
        self.expect("\*stopped,reason=\"exited-normally\"")

    @skipIfWindows  # llvm.org/pr24452: Get lldb-mi tests working on Windows
    @skipIfFreeBSD  # llvm.org/pr22411: Failure presumably due to known thread races
    @skipIfRemote   # We do not currently support remote debugging via the MI.
    @skipIfDarwin
    def test_lldbmi_specialchars(self):
        """Test that 'lldb-mi --interpreter' handles complicated strings."""

        # Create an alias for myexe
        complicated_myexe = self.getBuildArtifact("C--mpl-x file's`s @#$%^&*()_+-={}[]| name")
        os.symlink(self.myexe, complicated_myexe)
        self.addTearDownHook(lambda: os.unlink(complicated_myexe))

        self.spawnLldbMi(args="\"%s\"" % complicated_myexe)

        # Test that the executable was loaded
        self.expect(
            "-file-exec-and-symbols \"%s\"" %
            complicated_myexe, exactly=True)
        self.expect("\^done")

        # Check that it was loaded correctly
        self.runCmd("-break-insert -f main")
        self.expect("\^done,bkpt={number=\"1\"")
        self.runCmd("-exec-run")
        self.expect("\^running")
        self.expect("\*stopped,reason=\"breakpoint-hit\"")

    @skipIfWindows  # llvm.org/pr24452: Get lldb-mi tests working on Windows
    @skipIfFreeBSD  # llvm.org/pr22411: Failure presumably due to known thread races
    @skipIfDarwin
    @skipIfRemote   # We do not currently support remote debugging via the MI.
    def test_lldbmi_output_grammar(self):
        """Test that 'lldb-mi --interpreter' uses standard output syntax."""

        self.spawnLldbMi(args=None)
        self.child.setecho(False)

        # Run all commands simultaneously
        self.runCmd("-unknown-command")
        self.runCmd("-interpreter-exec command help")
        self.runCmd("-file-exec-and-symbols %s" % self.myexe)
        self.runCmd("-break-insert -f main")
        self.runCmd("-gdb-set target-async off")
        self.runCmd("-exec-run")
        self.runCmd("-gdb-set target-async on")
        self.runCmd("-exec-continue")
        self.runCmd("-gdb-exit")

        # Test that the program's output matches to the following pattern:
        # ( async-record | stream-record )* [ result-record ] "(gdb)" nl
        async_record = "^[0-9]*(\*|\+|=).+?\n"  # 1
        stream_record = "^(~|@|&).+?\n"         # 2
        result_record = "^[0-9]*\^.+?\n"        # 3
        prompt = "^\(gdb\)\r\n"                 # 4
        command = "^\r\n"                       # 5 (it looks like empty line for pexpect)
        error = "^.+?\n"                        # 6
        import pexpect                          # 7 (EOF)
        all_patterns = [
            async_record,
            stream_record,
            result_record,
            prompt,
            command,
            error,
            pexpect.EOF]

        # Routines to get a bit-mask for the specified list of patterns
        def get_bit(pattern): return all_patterns.index(pattern)
        def get_mask(pattern): return 1 << get_bit(pattern)
        def or_op(x, y): return x | y
        def get_state(*args): return reduce(or_op, map(get_mask, args))

        next_state = get_state(command)
        while True:
            it = self.expect(all_patterns)
            matched_pattern = all_patterns[it]

            # Check that state is acceptable
            if not (next_state & get_mask(matched_pattern)):
                self.fail(
                    "error: inconsistent pattern '%s' for state %#x (matched string: %s)" %
                    (repr(matched_pattern), next_state, self.child.after))
            elif matched_pattern == async_record or matched_pattern == stream_record:
                next_state = get_state(
                    async_record,
                    stream_record,
                    result_record,
                    prompt)
            elif matched_pattern == result_record:
                # FIXME lldb-mi prints async-records out of turn
                # ```
                #   ^done
                #   (gdb)
                #   ^running
                #   =thread-group-started,id="i1",pid="13875"
                #   (gdb)
                # ```
                # Therefore to pass that test I changed the grammar's rule:
                #   next_state = get_state(prompt)
                # to:
                next_state = get_state(async_record, prompt)
            elif matched_pattern == prompt:
                # FIXME lldb-mi prints the prompt out of turn
                # ```
                #   ^done
                #   (gdb)
                #   ^running
                #   (gdb)
                #   (gdb)
                # ```
                # Therefore to pass that test I changed the grammar's rule:
                #   next_state = get_state(async_record, stream_record, result_record, command, pexpect.EOF)
                # to:
                next_state = get_state(
                    async_record,
                    stream_record,
                    result_record,
                    prompt,
                    command,
                    pexpect.EOF)
            elif matched_pattern == command:
                next_state = get_state(
                    async_record,
                    stream_record,
                    result_record)
            elif matched_pattern == pexpect.EOF:
                break
            else:
                self.fail("error: pexpect returned an unknown state")
