"""
This tests that we do not lose control of the inferior, while doing an instruction-level step
over a thread creation instruction.
"""

from __future__ import print_function


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


class CreateDuringInstructionStepTestCase(TestBase):

    mydir = TestBase.compute_mydir(__file__)
    NO_DEBUG_INFO_TESTCASE = True

    @skipUnlessPlatform(['linux'])
    @expectedFailureAndroid('llvm.org/pr24737', archs=['arm'])
    @expectedFailureAll(
        oslist=["linux"],
        archs=["arm"],
        bugnumber="llvm.org/pr24737")
    def test_step_inst(self):
        self.build(dictionary=self.getBuildFlags())
        exe = self.getBuildArtifact("a.out")
        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target and target.IsValid(), "Target is valid")

        # This should create a breakpoint in the stepping thread.
        breakpoint = target.BreakpointCreateByName("main")
        self.assertTrue(
            breakpoint and breakpoint.IsValid(),
            "Breakpoint is valid")

        # Run the program.
        process = target.LaunchSimple(
            None, None, self.get_process_working_directory())
        self.assertTrue(process and process.IsValid(), PROCESS_IS_VALID)

        # The stop reason of the thread should be breakpoint.
        self.assertEqual(
            process.GetState(),
            lldb.eStateStopped,
            PROCESS_STOPPED)

        threads = lldbutil.get_threads_stopped_at_breakpoint(
            process, breakpoint)
        self.assertEqual(len(threads), 1, STOPPED_DUE_TO_BREAKPOINT)

        thread = threads[0]
        self.assertTrue(thread and thread.IsValid(), "Thread is valid")

        # Make sure we see only one threads
        self.assertEqual(
            process.GetNumThreads(),
            1,
            'Number of expected threads and actual threads do not match.')

        # Keep stepping until we see the thread creation
        while process.GetNumThreads() < 2:
            thread.StepInstruction(False)
            self.assertEqual(
                process.GetState(),
                lldb.eStateStopped,
                PROCESS_STOPPED)
            self.assertEqual(
                thread.GetStopReason(),
                lldb.eStopReasonPlanComplete,
                "Step operation succeeded")
            if self.TraceOn():
                self.runCmd("disassemble --pc")

        if self.TraceOn():
            self.runCmd("thread list")

        # We have successfully caught thread creation. Now just run to
        # completion
        process.Continue()

        # At this point, the inferior process should have exited.
        self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED)
