"""
Test that lldb can target and debug an executable whose path is longer than the
Windows MAX_PATH limit (260 characters).
"""

import os
import shutil

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

MAX_PATH = 260


@skipUnlessWindows
class LongPathTargetTestCase(TestBase):
    NO_DEBUG_INFO_TESTCASE = True

    def _long_path(self, path):
        return lldbutil.get_extended_windows_path(path)

    def _normalize(self, path):
        if path.startswith("\\\\?\\"):
            path = path[4:]
        return os.path.normcase(os.path.normpath(path))

    def _make_long_dir(self):
        """Create (and return) a directory whose absolute path comfortably
        exceeds MAX_PATH, or None if the OS refuses to create it."""
        components = [self.getBuildArtifact("deep")] + ["d" * 80] * 3
        target_dir = os.path.join(*components)
        try:
            os.makedirs(self._long_path(target_dir), exist_ok=True)
        except OSError:
            return None
        return target_dir

    def _find_module(self, target, long_exe):
        """Return the module in `target` whose path matches `long_exe`, or an
        invalid module if none does."""
        wanted = self._normalize(long_exe)
        for i in range(target.GetNumModules()):
            mod = target.GetModuleAtIndex(i)
            if self._normalize(mod.GetFileSpec().fullpath) == wanted:
                return mod
        return lldb.SBModule()

    def test_target_with_long_path(self):
        """CreateTarget, launch and break in an executable located past
        MAX_PATH, and verify the full path is preserved (not truncated)."""
        self.build()
        src_exe = self.getBuildArtifact("a.out")

        long_dir = self._make_long_dir()
        if long_dir is None:
            self.skipTest("OS cannot create paths longer than MAX_PATH")

        exe_basename = os.path.basename(src_exe)
        long_exe = os.path.join(long_dir, exe_basename)
        shutil.copyfile(src_exe, self._long_path(long_exe))

        long_exe_abs = os.path.abspath(long_exe)
        self.assertGreater(
            len(long_exe_abs),
            MAX_PATH,
            "the test executable path must exceed MAX_PATH to be meaningful",
        )

        # Creating the target has to open and parse the file at the long path.
        target = self.dbg.CreateTarget(long_exe)
        self.assertTrue(target.IsValid(), VALID_TARGET)

        # The main executable module must report its full, untruncated path.
        module = self._find_module(target, long_exe)
        self.assertTrue(
            module.IsValid(),
            "the executable module should be found by its full long path",
        )
        self.assertGreater(
            len(module.GetFileSpec().fullpath), MAX_PATH, "module path truncated"
        )

        bp = target.BreakpointCreateByName("main", exe_basename)
        self.assertGreater(bp.GetNumLocations(), 0, "main breakpoint has a location")

        process = target.LaunchSimple(None, None, self.get_process_working_directory())
        self.assertTrue(process.IsValid(), PROCESS_IS_VALID)
        self.assertState(
            process.GetState(), lldb.eStateStopped, "process stopped at main"
        )

        thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
        self.assertIsNotNone(thread, "stopped at the main breakpoint")
        self.assertEqual(thread.GetFrameAtIndex(0).GetFunctionName(), "main")

        # After launch the loaded executable module still carries the full path.
        live_module = self._find_module(process.GetTarget(), long_exe)
        self.assertTrue(live_module.IsValid(), "loaded module found by long path")
        self.assertGreater(
            len(live_module.GetFileSpec().fullpath),
            MAX_PATH,
            "loaded module path truncated",
        )

        process.Continue()
        self.assertState(process.GetState(), lldb.eStateExited)
        self.assertEqual(process.GetExitStatus(), 0)
