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

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 ChangeProcessGroupTestCase(TestBase):

    mydir = TestBase.compute_mydir(__file__)
    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
    @skipIfWindows  # setpgid call does not exist on Windows
    @expectedFailureAndroid("http://llvm.org/pr23762", api_levels=[16])
    @expectedFailureAll(oslist=['ios', 'watchos', 'tvos', 'bridgeos'], bugnumber="<rdar://problem/34538611>") # old lldb-server has race condition, launching an inferior and then launching debugserver in quick succession sometimes fails
    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])
        self.addTearDownHook(self.cleanupSubprocesses)

        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() and 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.assertEqual(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.assertEqual(process.GetState(), lldb.eStateExited)
