"""Test that we handle inferiors which change their process group"""


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


@requireNotWasm("no fork()/setpgid() on WebAssembly")
class ChangeProcessGroupTestCase(TestBase):
    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.c", "// Set breakpoint here")

    @skipIfFreeBSD  # Times out on FreeBSD llvm.org/pr23731
    @requirePOSIX  # setpgid call does not exist on Windows
    @expectedFailureAndroid("http://llvm.org/pr23762", api_levels=[16])
    @expectedFailureNetBSD
    @skipIftvOS  # fork not available on tvOS.
    @skipIfwatchOS  # fork not available on watchOS.
    def test_setpgid(self):
        self.build()
        exe = self.getBuildArtifact("a.out")

        # Use a file as a synchronization point between test and inferior.
        pid_file_path = lldbutil.append_to_process_working_directory(
            self, "pid_file_%d" % (int(time.time()))
        )
        self.addTearDownHook(
            lambda: self.run_platform_command("rm %s" % (pid_file_path))
        )

        popen = self.spawnSubprocess(exe, [pid_file_path])

        pid = lldbutil.wait_for_file_on_target(self, pid_file_path)

        # make sure we cleanup the forked child also
        def cleanupChild():
            if lldb.remote_platform:
                lldb.remote_platform.Kill(int(pid))
            else:
                if os.path.exists("/proc/" + pid):
                    os.kill(int(pid), signal.SIGKILL)

        self.addTearDownHook(cleanupChild)

        # Create a target by the debugger.
        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)

        listener = lldb.SBListener("my.attach.listener")
        error = lldb.SBError()
        process = target.AttachToProcessWithID(listener, int(pid), error)
        self.assertTrue(error.Success() and process, PROCESS_IS_VALID)

        # set a breakpoint just before the setpgid() call
        lldbutil.run_break_set_by_file_and_line(
            self, "main.c", self.line, num_expected_locations=-1
        )

        thread = process.GetSelectedThread()

        # release the child from its loop
        value = thread.GetSelectedFrame().EvaluateExpression("release_child_flag = 1")
        self.assertTrue(value.IsValid())
        self.assertEqual(value.GetValueAsUnsigned(0), 1)
        process.Continue()

        # make sure the child's process group id is different from its pid
        value = thread.GetSelectedFrame().EvaluateExpression("(int)getpgid(0)")
        self.assertTrue(value.IsValid())
        self.assertNotEqual(value.GetValueAsUnsigned(0), int(pid))

        # step over the setpgid() call
        thread.StepOver()
        self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonPlanComplete)

        # verify that the process group has been set correctly
        # this also checks that we are still in full control of the child
        value = thread.GetSelectedFrame().EvaluateExpression("(int)getpgid(0)")
        self.assertTrue(value.IsValid())
        self.assertEqual(value.GetValueAsUnsigned(0), int(pid))

        # run to completion
        process.Continue()
        self.assertState(process.GetState(), lldb.eStateExited)
