## @file
# Unit tests for workspace macro expansion.
#
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: BSD-2-Clause-Patent
#

"""Regression tests for workspace macro expansion."""

import os
import tempfile
import unittest
from unittest import mock

from Common.MultipleWorkspace import MultipleWorkspace


class TestMultipleWorkspace(unittest.TestCase):
    """Check workspace resolution without changing compiler option formatting."""

    def setUp(self) -> None:
        """Create isolated roots and restore shared workspace state after each test."""
        temporary = tempfile.TemporaryDirectory(prefix="multiple workspace ")
        self.addCleanup(temporary.cleanup)
        self.workspace = os.path.join(temporary.name, "workspace")
        self.packages = [
            os.path.join(temporary.name, "first package"),
            os.path.join(temporary.name, "last package"),
        ]
        for directory in [self.workspace] + self.packages:
            os.mkdir(directory)
        self.addCleanup(setattr, MultipleWorkspace, "WORKSPACE", MultipleWorkspace.WORKSPACE)
        self.addCleanup(setattr, MultipleWorkspace, "PACKAGES_PATH", MultipleWorkspace.PACKAGES_PATH)
        MultipleWorkspace.setWs(self.workspace, os.pathsep.join(self.packages))

    def create_file(self, root: str, relative: str) -> str:
        """Create an empty file under a test root and return its path."""
        path = os.path.join(root, relative)
        os.makedirs(os.path.dirname(path), exist_ok=True)
        with open(path, "w"):
            pass
        return path

    def test_workspace_takes_precedence(self) -> None:
        """Prefer an existing workspace file regardless of option quoting."""
        relative = "Config/Settings.txt"
        self.create_file(self.workspace, relative)
        self.create_file(self.packages[0], relative)
        for quote in ("", '"', "'"):
            with self.subTest(quote=quote):
                option = "--config=" + quote + "$(WORKSPACE)/" + relative + quote
                self.assertEqual(
                    option.replace("$(WORKSPACE)", self.workspace),
                    MultipleWorkspace.handleWsMacro(option),
                )

    def test_quoted_paths_with_spaces(self) -> None:
        """Resolve quoted paths with spaces while retaining their original quoting."""
        relative = "Config/Build Settings.txt"
        self.create_file(self.packages[0], relative)
        for option in (
            '"$(WORKSPACE)/Config/Build Settings.txt"',
            '--config="$(WORKSPACE)/Config/Build Settings.txt"',
            "--config='$(WORKSPACE)/Config/Build Settings.txt'",
            '"--config=$(WORKSPACE)/Config/Build Settings.txt"',
            "'--config=$(WORKSPACE)/Config/Build Settings.txt'",
            '--config="$(WORKSPACE)"/Config/"Build Settings.txt"',
        ):
            with self.subTest(option=option):
                self.assertEqual(
                    option.replace("$(WORKSPACE)", self.packages[0]),
                    MultipleWorkspace.handleWsMacro(option),
                )

    def test_opposite_quote_inside_quoted_path(self) -> None:
        """Preserve a literal apostrophe inside a double-quoted filename."""
        relative = "Config/Developer's Settings.txt"
        self.create_file(self.packages[0], relative)
        option = '--config="$(WORKSPACE)/' + relative + '"'
        self.assertEqual(
            option.replace("$(WORKSPACE)", self.packages[0]),
            MultipleWorkspace.handleWsMacro(option),
        )

    def test_first_existing_package_path_wins(self) -> None:
        """Prefer the first package root containing an unquoted path."""
        relative = "Include/Header.h"
        for directory in self.packages:
            self.create_file(directory, relative)
        option = "-I$(WORKSPACE)/" + relative
        self.assertEqual(
            option.replace("$(WORKSPACE)", self.packages[0]),
            MultipleWorkspace.handleWsMacro(option),
        )

    def test_later_package_path_is_searched(self) -> None:
        """Search later package roots when earlier roots lack the file."""
        relative = "Include/Header.h"
        self.create_file(self.packages[1], relative)
        option = '-I"$(WORKSPACE)/' + relative + '"'
        self.assertEqual(
            option.replace("$(WORKSPACE)", self.packages[1]),
            MultipleWorkspace.handleWsMacro(option),
        )

    def test_missing_path_stays_workspace_relative(self) -> None:
        """Keep missing paths rooted in the workspace rather than a package root."""
        for option in ("-I$(WORKSPACE)/Missing", '-I"$(WORKSPACE)/Missing Directory"'):
            with self.subTest(option=option):
                self.assertEqual(
                    option.replace("$(WORKSPACE)", self.workspace),
                    MultipleWorkspace.handleWsMacro(option),
                )

    def test_no_package_paths(self) -> None:
        """Expand the workspace macro when no package roots are configured."""
        MultipleWorkspace.setWs(self.workspace)
        option = '"$(WORKSPACE)/Missing Directory"'
        self.assertEqual(
            option.replace("$(WORKSPACE)", self.workspace),
            MultipleWorkspace.handleWsMacro(option),
        )

    def test_no_macro_is_unchanged(self) -> None:
        """Leave strings without a workspace macro unchanged."""
        for option in ("", '  -O2\t-DNAME="a b"  ', "$(OTHER)/Include"):
            with self.subTest(option=option):
                self.assertEqual(option, MultipleWorkspace.handleWsMacro(option))

    def test_multiple_options_preserve_whitespace_and_quotes(self) -> None:
        """Resolve each option independently without changing surrounding whitespace."""
        self.create_file(self.workspace, "Config/Settings.txt")
        self.create_file(self.packages[0], "Include/Header.h")
        option = '  -O2\t--config="$(WORKSPACE)/Config/Settings.txt"  -I$(WORKSPACE)/Include/Header.h\n'
        expected = (
            '  -O2\t--config="'
            + self.workspace
            + '/Config/Settings.txt"  -I'
            + self.packages[0]
            + "/Include/Header.h\n"
        )
        self.assertEqual(expected, MultipleWorkspace.handleWsMacro(option))

    def test_windows_backslashes_are_preserved(self) -> None:
        """Check Windows-style paths without treating backslashes as escapes."""
        MultipleWorkspace.WORKSPACE = r"C:\Main Workspace"
        MultipleWorkspace.PACKAGES_PATH = [r"D:\First Package", r"E:\Last Package"]
        option = r'/I"$(WORKSPACE)\Include Files\Header.h"'
        path = r"D:\First Package\Include Files\Header.h"
        with mock.patch("Common.LongFilePathOs.path.exists", side_effect=lambda candidate: candidate == path) as exists:
            self.assertEqual(
                option.replace("$(WORKSPACE)", MultipleWorkspace.PACKAGES_PATH[0]),
                MultipleWorkspace.handleWsMacro(option),
            )
            self.assertEqual(
                [
                    mock.call(r"C:\Main Workspace\Include Files\Header.h"),
                    mock.call(path),
                ],
                exists.call_args_list,
            )


def TheTestSuite() -> unittest.TestSuite:
    """Return the regression suite for the BaseTools test runner."""
    return unittest.defaultTestLoader.loadTestsFromTestCase(TestMultipleWorkspace)


if __name__ == "__main__":
    unittest.main()
