"""
Test some lldb command abbreviations.
"""
from __future__ import print_function


import lldb
import os
import time
from lldbsuite.support import seven
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil


def execute_command(command):
    #print('%% %s' % (command))
    (exit_status, output) = seven.get_command_status_output(command)
    # if output:
    #    print(output)
    #print('status = %u' % (exit_status))
    return exit_status


class ExecTestCase(TestBase):

    NO_DEBUG_INFO_TESTCASE = True

    mydir = TestBase.compute_mydir(__file__)

    @skipUnlessDarwin
    @expectedFailureAll(archs=['i386'], bugnumber="rdar://28656532")
    @expectedFailureAll(oslist=["ios", "tvos", "watchos", "bridgeos"], bugnumber="rdar://problem/34559552") # this exec test has problems on ios systems
    def test_hitting_exec (self):
        self.do_test(False)

    @skipUnlessDarwin
    @expectedFailureAll(archs=['i386'], bugnumber="rdar://28656532")
    @expectedFailureAll(oslist=["ios", "tvos", "watchos", "bridgeos"], bugnumber="rdar://problem/34559552") # this exec test has problems on ios systems
    def test_skipping_exec (self):
        self.do_test(True)

    def do_test(self, skip_exec):
        self.build()
        exe = self.getBuildArtifact("a.out")
        secondprog = self.getBuildArtifact("secondprog")

        # Create the target
        target = self.dbg.CreateTarget(exe)

        # Create any breakpoints we need
        breakpoint1 = target.BreakpointCreateBySourceRegex(
            'Set breakpoint 1 here', lldb.SBFileSpec("main.cpp", False))
        self.assertTrue(breakpoint1, VALID_BREAKPOINT)
        breakpoint2 = target.BreakpointCreateBySourceRegex(
            'Set breakpoint 2 here', lldb.SBFileSpec("secondprog.cpp", False))
        self.assertTrue(breakpoint2, VALID_BREAKPOINT)

        # Launch the process
        process = target.LaunchSimple(
            None, None, self.get_process_working_directory())
        self.assertTrue(process, PROCESS_IS_VALID)

        if skip_exec:
            self.dbg.HandleCommand("settings set target.process.stop-on-exec false")
            def cleanup():
                self.runCmd("settings set target.process.stop-on-exec false",
                            check=False)

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

        # The stop reason of the thread should be breakpoint.
        self.assertTrue(process.GetState() == lldb.eStateStopped,
                        STOPPED_DUE_TO_BREAKPOINT)

        threads = lldbutil.get_threads_stopped_at_breakpoint(
        process, breakpoint1)
        self.assertTrue(len(threads) == 1)

        # We had a deadlock tearing down the TypeSystemMap on exec, but only if some
        # expression had been evaluated.  So make sure we do that here so the teardown
        # is not trivial.

        thread = threads[0]
        value = thread.frames[0].EvaluateExpression("1 + 2")
        self.assertTrue(
            value.IsValid(),
            "Expression evaluated successfully")
        int_value = value.GetValueAsSigned()
        self.assertTrue(int_value == 3, "Expression got the right result.")

        # Run and we should stop due to exec
        process.Continue()

        if not skip_exec:
            self.assertTrue(process.GetState() == lldb.eStateStopped,
                            "Process should be stopped at __dyld_start")

            threads = lldbutil.get_stopped_threads(
                process, lldb.eStopReasonExec)
            self.assertTrue(
                len(threads) == 1,
                "We got a thread stopped for exec.")

            # Run and we should stop at breakpoint in main after exec
            process.Continue()

        threads = lldbutil.get_threads_stopped_at_breakpoint(
            process, breakpoint2)
        if self.TraceOn():
            for t in process.threads:
                print(t)
                if t.GetStopReason() != lldb.eStopReasonBreakpoint:
                    self.runCmd("bt")
        self.assertTrue(len(threads) == 1,
                        "Stopped at breakpoint in exec'ed process.")
