"""
Test process attach.
"""


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

exe_name = "ProcessAttach"  # Must match Makefile


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)

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

        target = self.dbg.GetSelectedTarget()

        process = target.GetProcess()
        self.assertTrue(process, PROCESS_IS_VALID)
        self.assertTrue(process.GetState(), lldb.eStateRunning)

    @skipIfWindows  # This is flakey on Windows AND when it fails, it hangs: llvm.org/pr48806
    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)
        self.addTearDownHook(lambda: shutil.rmtree(newdir))

        # 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)

    @skipIfWindows  # This test is flaky on Windows
    @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
        popen = self.spawnSubprocess(os.path.relpath(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"])

    def tearDown(self):
        # Destroy process before TestBase.tearDown()
        self.dbg.GetSelectedTarget().GetProcess().Destroy()

        # Call super's tearDown().
        TestBase.tearDown(self)
