"""
Test lldb process launch flags.
"""

import os

import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
from pathlib import Path


class ProcessLaunchTestCase(TestBase):
    NO_DEBUG_INFO_TESTCASE = True
    SHARED_BUILD_TESTCASE = False

    def setUp(self):
        # Call super's setUp().
        TestBase.setUp(self)
        self.runCmd("settings set auto-confirm true")

    def tearDown(self):
        self.runCmd("settings clear auto-confirm")
        TestBase.tearDown(self)

    @skipIfRemote
    def test_io(self):
        """Test that process launch I/O redirection flags work properly."""
        self.build()
        exe = self.getBuildArtifact("a.out")
        self.expect("file " + exe, patterns=["Current executable set to .*a.out"])

        in_file = os.path.join(self.getSourceDir(), "input-file.txt")
        out_file = lldbutil.append_to_process_working_directory(self, "output-test.out")
        err_file = lldbutil.append_to_process_working_directory(self, "output-test.err")

        # Make sure the output files do not exist before launching the process
        try:
            os.remove(out_file)
        except OSError:
            pass

        try:
            os.remove(err_file)
        except OSError:
            pass

        launch_command = "process launch -i '{0}' -o '{1}' -e '{2}' -w '{3}'".format(
            in_file, out_file, err_file, self.get_process_working_directory()
        )

        if lldb.remote_platform:
            self.runCmd(
                'platform put-file "{local}" "{remote}"'.format(
                    local=in_file, remote=in_file
                )
            )

        self.expect(launch_command, patterns=["Process .* launched: .*a.out"])

        success = True
        err_msg = ""

        out = lldbutil.read_file_on_target(self, out_file)
        if out != "This should go to stdout.\n":
            success = False
            err_msg = (
                err_msg + "    ERROR: stdout file does not contain correct output.\n"
            )

        err = lldbutil.read_file_on_target(self, err_file)
        if err != "This should go to stderr.\n":
            success = False
            err_msg = (
                err_msg + "    ERROR: stderr file does not contain correct output.\n"
            )

        if not success:
            self.fail(err_msg)

    # rdar://problem/9056462
    # The process launch flag '-w' for setting the current working directory
    # not working?
    @skipIfRemote
    @expectedFailureAll(oslist=["freebsd", "linux"], bugnumber="llvm.org/pr20265")
    @expectedFailureNetBSD
    def test_set_working_dir_nonexisting(self):
        """Test that '-w dir' fails to set the working dir when running the inferior with a dir which doesn't exist."""
        d = {"CXX_SOURCES": "print_cwd.cpp"}
        self.build(dictionary=d)
        self.setTearDownCleanup(d)
        exe = self.getBuildArtifact("a.out")
        self.runCmd("file " + exe)

        mywd = "my_working_dir"
        out_file_name = "my_working_dir_test.out"
        err_file_name = "my_working_dir_test.err"

        my_working_dir_path = self.getBuildArtifact(mywd)
        out_file_path = os.path.join(my_working_dir_path, out_file_name)
        err_file_path = os.path.join(my_working_dir_path, err_file_name)

        # Check that we get an error when we have a nonexisting path
        invalid_dir_path = mywd + "z"
        launch_command = "process launch -w %s -o %s -e %s" % (
            invalid_dir_path,
            out_file_path,
            err_file_path,
        )

        self.expect(
            launch_command,
            error=True,
            patterns=["error:.* No such file or directory: %s" % invalid_dir_path],
        )

    @skipIfRemote
    def test_set_working_dir_existing(self):
        """Test that '-w dir' sets the working dir when running the inferior."""
        d = {"CXX_SOURCES": "print_cwd.cpp"}
        self.build(dictionary=d)
        self.setTearDownCleanup(d)
        exe = self.getBuildArtifact("a.out")
        self.runCmd("file " + exe)

        mywd = "my_working_dir"
        out_file_name = "my_working_dir_test.out"
        err_file_name = "my_working_dir_test.err"

        my_working_dir_path = self.getBuildArtifact(mywd)
        lldbutil.mkdir_p(my_working_dir_path)
        out_file_path = os.path.join(my_working_dir_path, out_file_name)
        err_file_path = os.path.join(my_working_dir_path, err_file_name)

        # Make sure the output files do not exist before launching the process
        try:
            os.remove(out_file_path)
            os.remove(err_file_path)
        except OSError:
            pass

        launch_command = "process launch -w %s -o %s -e %s" % (
            my_working_dir_path,
            out_file_path,
            err_file_path,
        )

        self.expect(launch_command, patterns=["Process .* launched: .*a.out"])

        success = True
        err_msg = ""

        # Check to see if the 'stdout' file was created
        try:
            out_f = open(out_file_path)
        except IOError:
            success = False
            err_msg = err_msg + "ERROR: stdout file was not created.\n"
        else:
            # Check to see if the 'stdout' file contains the right output
            line = out_f.readline()
            if self.TraceOn():
                print("line:", line)
            if not re.search(mywd, line):
                success = False
                err_msg = (
                    err_msg + "The current working directory was not set correctly.\n"
                )
                out_f.close()

        # Try to delete the 'stdout' and 'stderr' files
        try:
            os.remove(out_file_path)
            os.remove(err_file_path)
        except OSError:
            pass

        if not success:
            self.fail(err_msg)

    def test_environment_with_special_char(self):
        """Test that environment variables containing '*' and '}' are handled correctly by the inferior."""
        source = "print_env.cpp"
        d = {"CXX_SOURCES": source}
        self.build(dictionary=d)
        self.setTearDownCleanup(d)

        evil_var = "INIT*MIDDLE}TAIL"

        target = self.createTestTarget()
        main_source_spec = lldb.SBFileSpec(source)
        breakpoint = target.BreakpointCreateBySourceRegex(
            "// Set breakpoint here.", main_source_spec
        )

        process = target.LaunchSimple(
            None, ["EVIL=" + evil_var], self.get_process_working_directory()
        )
        self.assertEqual(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)

        threads = lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint)
        self.assertEqual(len(threads), 1)
        frame = threads[0].GetFrameAtIndex(0)
        sbvalue = frame.EvaluateExpression("evil")
        value = sbvalue.GetSummary().strip('"')

        self.assertEqual(value, evil_var)
        process.Continue()
        self.assertState(process.GetState(), lldb.eStateExited, PROCESS_EXITED)

    @skipIfRemote
    def test_target_launch_working_dir_prop(self):
        """Test that the setting `target.launch-working-dir` is correctly used when launching a process."""
        d = {"CXX_SOURCES": "print_cwd.cpp"}
        self.build(dictionary=d)
        self.setTearDownCleanup(d)
        exe = self.getBuildArtifact("a.out")
        self.runCmd("file " + exe)

        mywd = "my_working_dir"
        out_file_name = "my_working_dir_test.out"

        my_working_dir_path = Path(self.getBuildArtifact(mywd)).resolve()
        lldbutil.mkdir_p(my_working_dir_path)
        out_file_path = os.path.join(my_working_dir_path, out_file_name)
        another_working_dir_path = Path(
            os.path.join(my_working_dir_path, "..")
        ).resolve()

        # If -w is not passed to process launch, then the setting will be used.
        self.runCmd(
            f"settings set target.launch-working-dir {another_working_dir_path}"
        )
        launch_command = f"process launch -o {out_file_path}"

        self.expect(
            launch_command,
            patterns=["Process .* launched: .*a.out"],
        )

        out = lldbutil.read_file_on_target(self, out_file_path)

        self.assertIn(f"stdout: {another_working_dir_path}", out)

        # If -w is passed to process launch, that value will be used instead of the setting.
        launch_command = f"process launch -w {my_working_dir_path} -o {out_file_path}"

        self.expect(
            launch_command,
            patterns=["Process .* launched: .*a.out"],
        )

        out = lldbutil.read_file_on_target(self, out_file_path)
        self.assertIn(f"stdout: {my_working_dir_path}", out)

        # If set to empty, then LLDB's cwd will be used to launch the process.
        self.runCmd(f"settings set target.launch-working-dir ''")
        launch_command = f"process launch -o {out_file_path}"

        self.expect(
            launch_command,
            patterns=["Process .* launched: .*a.out"],
        )

        out = lldbutil.read_file_on_target(self, out_file_path)
        self.assertNotIn(f"stdout: {another_working_dir_path}", out)
