"""
Test process attach.
"""


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

exe_name = "ProcessAttach"  # Must match Makefile


@requireNotWasm("attaching requires launching the inferior as a host process")
class ProcessAttachTestCase(TestBase):
    SHARED_BUILD_TESTCASE = False
    NO_DEBUG_INFO_TESTCASE = True

    def setUp(self):
        # Call super's setUp().
        TestBase.setUp(self)
        # Find the line number to break for main.c.
        self.line = line_number("main.cpp", "// Waiting to be attached...")

    @skipIfiOSSimulator
    def test_attach_to_process_by_id(self):
        """Test attach by process id"""
        self.build()
        exe = self.getBuildArtifact(exe_name)

        # Spawn a new process
        popen = self.spawnSubprocess(exe)

        self.runCmd("process attach -p " + str(popen.pid))

        target = self.dbg.GetSelectedTarget()

        process = target.GetProcess()
        self.assertTrue(process, PROCESS_IS_VALID)

    @skipIfiOSSimulator
    def test_attach_to_process_by_id_autocontinue(self):
        """Test attach by process id"""
        self.build()
        exe = self.getBuildArtifact(exe_name)

        # Spawn a new process
        popen = self.spawnSubprocess(exe)

        # Don't wait for the continue to finish.
        self.setAsync(True)
        self.runCmd("process attach -c -p " + str(popen.pid))

        target = self.dbg.GetSelectedTarget()

        # Start listening to process events.
        process = target.GetProcess()
        self.assertTrue(process, PROCESS_IS_VALID)
        broadcaster = process.GetBroadcaster()
        listener = self.dbg.GetListener()
        state = process.GetState()
        self.assertEqual(
            state, lldb.eStateStopped, "The attach stopped before continuing"
        )

        # Listen for events until we see the process continue.
        event = lldb.SBEvent()
        got_running = False
        got_event = False
        timeout = 180
        while listener.WaitForEventForBroadcaster(timeout, broadcaster, event):
            state = process.GetState()
            got_event = True
            if state == lldb.eStateRunning:
                got_running = True
                break

        self.assertTrue(got_event, "Didn't receive any events after attaching")
        self.assertTrue(got_running, "Process didn't auto-continue")

    def test_attach_to_process_from_different_dir_by_id(self):
        """Test attach by process id"""
        newdir = self.getBuildArtifact("newdir")
        os.makedirs(newdir, exist_ok=True)
        testdir = self.getBuildDir()
        exe = os.path.join(newdir, "proc_attach")
        self.buildProgram("main.cpp", exe)

        # Spawn a new process
        popen = self.spawnSubprocess(exe)

        os.chdir(newdir)
        sourcedir = self.getSourceDir()
        self.addTearDownHook(lambda: os.chdir(sourcedir))
        self.runCmd("process attach -p " + str(popen.pid))

        target = self.dbg.GetSelectedTarget()

        process = target.GetProcess()
        self.assertTrue(process, PROCESS_IS_VALID)

    def test_attach_to_process_by_name(self):
        """Test attach by process name"""
        self.build()
        exe = self.getBuildArtifact(exe_name)

        # Spawn a new process
        popen = self.spawnSubprocess(exe)

        self.runCmd("process attach -n " + exe_name)

        target = self.dbg.GetSelectedTarget()

        process = target.GetProcess()
        self.assertTrue(process, PROCESS_IS_VALID)

    @expectedFailureNetBSD
    def test_attach_to_process_by_id_correct_executable_offset(self):
        """
        Test that after attaching to a process the executable offset
        is determined correctly on FreeBSD.  This is a regression test
        for dyld plugin getting the correct executable path,
        and therefore being able to identify it in the module list.
        """

        self.build()
        exe = self.getBuildArtifact(exe_name)

        # In order to reproduce, we must spawn using a relative path.
        os.chdir(self.getBuildDir())
        sourcedir = self.getSourceDir()
        self.addTearDownHook(lambda: os.chdir(sourcedir))
        popen = self.spawnSubprocess(os.path.join(os.curdir, os.path.basename(exe)))

        self.runCmd("process attach -p " + str(popen.pid))

        # Make sure we did not attach too early.
        lldbutil.run_break_set_by_file_and_line(
            self, "main.cpp", self.line, num_expected_locations=1, loc_exact=False
        )
        self.runCmd("process continue")
        self.expect("v g_val", substrs=["12345"])
