#
#  Copyright (C) 2018 Codethink Limited
#  Copyright (C) 2018 Bloomberg Finance LP
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU Lesser General Public
#  License as published by the Free Software Foundation; either
#  version 2 of the License, or (at your option) any later version.
#
#  This library is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#  Lesser General Public License for more details.
#
#  You should have received a copy of the GNU Lesser General Public
#  License along with this library. If not, see <http://www.gnu.org/licenses/>.
#
#  Authors: Tristan Van Berkom <tristan.vanberkom@codethink.co.uk>
#           Tristan Maat <tristan.maat@codethink.co.uk>
#           Chandan Singh <csingh43@bloomberg.net>
#           Phillip Smyth <phillip.smyth@codethink.co.uk>
#           Jonathan Maw <jonathan.maw@codethink.co.uk>
#           Richard Maw <richard.maw@codethink.co.uk>
#           William Salmon <will.salmon@codethink.co.uk>
#

# Pylint doesn't play well with fixtures and dependency injection from pytest
# pylint: disable=redefined-outer-name

import os
import stat
import shutil
import subprocess

import pytest

from buildstream.testing import create_repo, ALL_REPO_KINDS
from buildstream.testing import cli  # pylint: disable=unused-import
from buildstream import _yaml
from buildstream.exceptions import ErrorDomain, LoadErrorReason
from buildstream._workspaces import BST_WORKSPACE_FORMAT_VERSION

from tests.testutils import create_artifact_share, create_element_size, wait_for_cache_granularity

repo_kinds = ALL_REPO_KINDS

# Project directory
DATA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "project",)
BASE_FILENAME = os.path.basename(__file__)


class WorkspaceCreator:
    def __init__(self, cli, tmpdir, datafiles, project_path=None):
        self.cli = cli
        self.tmpdir = tmpdir
        self.datafiles = datafiles

        if not project_path:
            project_path = str(datafiles)
        else:
            shutil.copytree(str(datafiles), project_path)

        self.project_path = project_path
        self.bin_files_path = os.path.join(project_path, "files", "bin-files")

        self.workspace_cmd = os.path.join(self.project_path, "workspace_cmd")

    def create_workspace_element(self, kind, suffix="", workspace_dir=None, element_attrs=None):
        element_name = "workspace-test-{}{}.bst".format(kind, suffix)
        element_path = os.path.join(self.project_path, "elements")
        if not workspace_dir:
            workspace_dir = os.path.join(self.workspace_cmd, element_name)
            if workspace_dir[-4:] == ".bst":
                workspace_dir = workspace_dir[:-4]

        # Create our repo object of the given source type with
        # the bin files, and then collect the initial ref.
        repo = create_repo(kind, str(self.tmpdir))
        ref = repo.create(self.bin_files_path)

        # Write out our test target
        element = {"kind": "import", "sources": [repo.source_config(ref=ref)]}
        if element_attrs:
            element = {**element, **element_attrs}
        _yaml.roundtrip_dump(element, os.path.join(element_path, element_name))
        return element_name, element_path, workspace_dir

    def create_workspace_elements(self, kinds, suffixs=None, workspace_dir_usr=None, element_attrs=None):

        element_tuples = []

        if suffixs is None:
            suffixs = ["",] * len(kinds)
        else:
            if len(suffixs) != len(kinds):
                raise "terable error"

        for suffix, kind in zip(suffixs, kinds):
            element_name, _, workspace_dir = self.create_workspace_element(
                kind, suffix, workspace_dir_usr, element_attrs
            )
            element_tuples.append((element_name, workspace_dir))

        # Assert that there is a fetch is needed
        states = self.cli.get_element_states(self.project_path, [e for e, _ in element_tuples])
        assert not any(states[e] != "fetch needed" for e, _ in element_tuples)

        return element_tuples

    def open_workspaces(self, kinds, suffixs=None, workspace_dir=None, element_attrs=None, no_checkout=False):

        element_tuples = self.create_workspace_elements(kinds, suffixs, workspace_dir, element_attrs)
        os.makedirs(self.workspace_cmd, exist_ok=True)

        # Now open the workspace, this should have the effect of automatically
        # tracking & fetching the source from the repo.
        args = ["workspace", "open"]
        if no_checkout:
            args.append("--no-checkout")
        if workspace_dir is not None:
            assert len(element_tuples) == 1, "test logic error"
            _, workspace_dir = element_tuples[0]
            args.extend(["--directory", workspace_dir])

        args.extend([element_name for element_name, workspace_dir_suffix in element_tuples])
        result = self.cli.run(cwd=self.workspace_cmd, project=self.project_path, args=args)

        result.assert_success()

        if not no_checkout:
            # Assert that we are now buildable because the source is now cached.
            states = self.cli.get_element_states(self.project_path, [e for e, _ in element_tuples])
            assert not any(states[e] != "buildable" for e, _ in element_tuples)

            # Check that the executable hello file is found in each workspace
            for _, workspace in element_tuples:
                filename = os.path.join(workspace, "usr", "bin", "hello")
                assert os.path.exists(filename)

        return element_tuples


def open_workspace(
    cli,
    tmpdir,
    datafiles,
    kind,
    suffix="",
    workspace_dir=None,
    project_path=None,
    element_attrs=None,
    no_checkout=False,
):
    workspace_object = WorkspaceCreator(cli, tmpdir, datafiles, project_path)
    workspaces = workspace_object.open_workspaces((kind,), (suffix,), workspace_dir, element_attrs, no_checkout)
    assert len(workspaces) == 1
    element_name, workspace = workspaces[0]
    return element_name, workspace_object.project_path, workspace


@pytest.mark.datafiles(DATA_DIR)
def test_open_bzr_customize(cli, tmpdir, datafiles):
    element_name, project, workspace = open_workspace(cli, tmpdir, datafiles, "bzr")

    # Check that the .bzr dir exists
    bzrdir = os.path.join(workspace, ".bzr")
    assert os.path.isdir(bzrdir)

    # Check that the correct origin branch is set
    element_config = _yaml.load(os.path.join(project, "elements", element_name), shortname=None)
    source_config = element_config.get_sequence("sources").mapping_at(0)
    output = subprocess.check_output(["bzr", "info"], cwd=workspace)
    stripped_url = source_config.get_str("url").lstrip("file:///")
    expected_output_str = "checkout of branch: /{}/{}".format(stripped_url, source_config.get_str("track"))
    assert expected_output_str in str(output)


@pytest.mark.datafiles(DATA_DIR)
def test_open_multi(cli, tmpdir, datafiles):

    workspace_object = WorkspaceCreator(cli, tmpdir, datafiles)
    workspaces = workspace_object.open_workspaces(repo_kinds)

    for (elname, workspace), kind in zip(workspaces, repo_kinds):
        assert kind in elname
        workspace_lsdir = os.listdir(workspace)
        if kind == "git":
            assert ".git" in workspace_lsdir
        elif kind == "bzr":
            assert ".bzr" in workspace_lsdir
        else:
            assert ".git" not in workspace_lsdir
            assert ".bzr" not in workspace_lsdir


@pytest.mark.skipif(os.geteuid() == 0, reason="root may have CAP_DAC_OVERRIDE and ignore permissions")
@pytest.mark.datafiles(DATA_DIR)
def test_open_multi_unwritable(cli, tmpdir, datafiles):
    workspace_object = WorkspaceCreator(cli, tmpdir, datafiles)

    element_tuples = workspace_object.create_workspace_elements(repo_kinds, repo_kinds)
    os.makedirs(workspace_object.workspace_cmd, exist_ok=True)

    # Now open the workspace, this should have the effect of automatically
    # tracking & fetching the source from the repo.
    args = ["workspace", "open"]
    args.extend([element_name for element_name, workspace_dir_suffix in element_tuples])
    cli.configure({"workspacedir": workspace_object.workspace_cmd})

    cwdstat = os.stat(workspace_object.workspace_cmd)
    try:
        os.chmod(workspace_object.workspace_cmd, cwdstat.st_mode - stat.S_IWRITE)
        result = workspace_object.cli.run(project=workspace_object.project_path, args=args)
    finally:
        # Using this finally to make sure we always put thing back how they should be.
        os.chmod(workspace_object.workspace_cmd, cwdstat.st_mode)

    result.assert_main_error(ErrorDomain.STREAM, None)
    # Normally we avoid checking stderr in favour of using the mechine readable result.assert_main_error
    # But Tristan was very keen that the names of the elements left needing workspaces were present in the out put
    assert " ".join([element_name for element_name, workspace_dir_suffix in element_tuples[1:]]) in result.stderr


@pytest.mark.datafiles(DATA_DIR)
def test_open_multi_with_directory(cli, tmpdir, datafiles):
    workspace_object = WorkspaceCreator(cli, tmpdir, datafiles)

    element_tuples = workspace_object.create_workspace_elements(repo_kinds, repo_kinds)
    os.makedirs(workspace_object.workspace_cmd, exist_ok=True)

    # Now open the workspace, this should have the effect of automatically
    # tracking & fetching the source from the repo.
    args = ["workspace", "open"]
    args.extend(["--directory", "any/dir/should/fail"])

    args.extend([element_name for element_name, workspace_dir_suffix in element_tuples])
    result = workspace_object.cli.run(
        cwd=workspace_object.workspace_cmd, project=workspace_object.project_path, args=args
    )

    result.assert_main_error(ErrorDomain.STREAM, "directory-with-multiple-elements")


@pytest.mark.datafiles(DATA_DIR)
def test_open_defaultlocation(cli, tmpdir, datafiles):
    workspace_object = WorkspaceCreator(cli, tmpdir, datafiles)

    # pylint: disable=unbalanced-tuple-unpacking
    ((element_name, workspace_dir),) = workspace_object.create_workspace_elements(["git"], ["git"])
    os.makedirs(workspace_object.workspace_cmd, exist_ok=True)

    # Now open the workspace, this should have the effect of automatically
    # tracking & fetching the source from the repo.
    args = ["workspace", "open"]
    args.append(element_name)

    # In the other tests we set the cmd to workspace_object.workspace_cmd with the optional
    # argument, cwd for the workspace_object.cli.run function. But hear we set the default
    # workspace location to workspace_object.workspace_cmd and run the cli.run function with
    # no cwd option so that it runs in the project directory.
    cli.configure({"workspacedir": workspace_object.workspace_cmd})
    result = workspace_object.cli.run(project=workspace_object.project_path, args=args)

    result.assert_success()

    assert cli.get_element_state(workspace_object.project_path, element_name) == "buildable"

    # Check that the executable hello file is found in the workspace
    # even though the cli.run function was not run with cwd = workspace_object.workspace_cmd
    # the workspace should be created in there as we used the 'workspacedir' configuration
    # option.
    filename = os.path.join(workspace_dir, "usr", "bin", "hello")
    assert os.path.exists(filename)


@pytest.mark.datafiles(DATA_DIR)
def test_open_defaultlocation_exists(cli, tmpdir, datafiles):
    workspace_object = WorkspaceCreator(cli, tmpdir, datafiles)

    # pylint: disable=unbalanced-tuple-unpacking
    ((element_name, workspace_dir),) = workspace_object.create_workspace_elements(["git"], ["git"])
    os.makedirs(workspace_object.workspace_cmd, exist_ok=True)

    with open(workspace_dir, "w", encoding="utf-8") as fl:
        fl.write("foo")

    # Now open the workspace, this should have the effect of automatically
    # tracking & fetching the source from the repo.
    args = ["workspace", "open"]
    args.append(element_name)

    # In the other tests we set the cmd to workspace_object.workspace_cmd with the optional
    # argument, cwd for the workspace_object.cli.run function. But hear we set the default
    # workspace location to workspace_object.workspace_cmd and run the cli.run function with
    # no cwd option so that it runs in the project directory.
    cli.configure({"workspacedir": workspace_object.workspace_cmd})
    result = workspace_object.cli.run(project=workspace_object.project_path, args=args)

    result.assert_main_error(ErrorDomain.STREAM, "bad-directory")


@pytest.mark.datafiles(DATA_DIR)
def test_open_track(cli, tmpdir, datafiles):
    open_workspace(cli, tmpdir, datafiles, "git")


@pytest.mark.datafiles(DATA_DIR)
def test_open_noclose_open(cli, tmpdir, datafiles):
    # opening the same workspace twice without closing it should fail
    element_name, project, _ = open_workspace(cli, tmpdir, datafiles, "git")

    result = cli.run(project=project, args=["workspace", "open", element_name])
    result.assert_main_error(ErrorDomain.STREAM, None)


@pytest.mark.datafiles(DATA_DIR)
def test_open_force(cli, tmpdir, datafiles):
    element_name, project, workspace = open_workspace(cli, tmpdir, datafiles, "git")

    # Close the workspace
    result = cli.run(project=project, args=["workspace", "close", element_name])
    result.assert_success()

    # Assert the workspace dir still exists
    assert os.path.exists(workspace)

    # Now open the workspace again with --force, this should happily succeed
    result = cli.run(project=project, args=["workspace", "open", "--force", "--directory", workspace, element_name])
    result.assert_success()


@pytest.mark.datafiles(DATA_DIR)
def test_open_force_open(cli, tmpdir, datafiles):
    element_name, project, workspace = open_workspace(cli, tmpdir, datafiles, "git")

    result = cli.run(project=project, args=["workspace", "close", element_name])
    result.assert_success()

    # Assert the workspace dir exists
    assert os.path.exists(workspace)

    # Now open the workspace again with --force, this should happily succeed
    result = cli.run(project=project, args=["workspace", "open", "--force", "--directory", workspace, element_name])
    result.assert_success()


# Regression test for #1086.
@pytest.mark.datafiles(DATA_DIR)
def test_open_force_open_no_checkout(cli, tmpdir, datafiles):
    element_name, project, workspace = open_workspace(cli, tmpdir, datafiles, "git")
    hello_path = os.path.join(workspace, "hello.txt")

    # Assert the workspace dir exists
    assert os.path.exists(workspace)

    # Create a new file in the workspace
    with open(hello_path, "w", encoding="utf-8") as f:
        f.write("hello")

    # Now open the workspace again with --force and --no-checkout
    result = cli.run(
        project=project, args=["workspace", "open", "--force", "--no-checkout", "--directory", workspace, element_name]
    )
    result.assert_success()

    # Ensure that our files were not overwritten
    assert os.path.exists(hello_path)
    with open(hello_path, encoding="utf-8") as f:
        assert f.read() == "hello"


@pytest.mark.datafiles(DATA_DIR)
def test_open_force_different_workspace(cli, tmpdir, datafiles):
    _, project, workspace = open_workspace(cli, tmpdir, datafiles, "git", "-alpha")

    # Assert the workspace dir exists
    assert os.path.exists(workspace)

    hello_path = os.path.join(workspace, "usr", "bin", "hello")
    hello1_path = os.path.join(workspace, "usr", "bin", "hello1")

    tmpdir = os.path.join(str(tmpdir), "-beta")
    shutil.move(hello_path, hello1_path)
    element_name2, _, workspace2 = open_workspace(cli, tmpdir, datafiles, "git", "-beta")

    # Assert the workspace dir exists
    assert os.path.exists(workspace2)

    # Assert that workspace 1 contains the modified file
    assert os.path.exists(hello1_path)

    # Assert that workspace 2 contains the unmodified file
    assert os.path.exists(os.path.join(workspace2, "usr", "bin", "hello"))

    result = cli.run(project=project, args=["workspace", "close", element_name2])
    result.assert_success()

    # Now open the workspace again with --force, this should happily succeed
    result = cli.run(project=project, args=["workspace", "open", "--force", "--directory", workspace, element_name2])
    result.assert_success()

    # Assert that the file in workspace 1 has been replaced
    # With the file from workspace 2
    assert os.path.exists(hello_path)
    assert not os.path.exists(hello1_path)


@pytest.mark.datafiles(DATA_DIR)
def test_close(cli, tmpdir, datafiles):
    element_name, project, workspace = open_workspace(cli, tmpdir, datafiles, "git")

    # Close the workspace
    result = cli.run(project=project, args=["workspace", "close", "--remove-dir", element_name])
    result.assert_success()

    # Assert the workspace dir has been deleted
    assert not os.path.exists(workspace)


@pytest.mark.datafiles(DATA_DIR)
def test_close_external_after_move_project(cli, tmpdir, datafiles):
    workspace_dir = os.path.join(str(tmpdir), "workspace")
    project_path = os.path.join(str(tmpdir), "initial_project")
    element_name, _, _ = open_workspace(cli, tmpdir, datafiles, "git", "", workspace_dir, project_path)
    assert os.path.exists(workspace_dir)
    moved_dir = os.path.join(str(tmpdir), "external_project")
    shutil.move(project_path, moved_dir)
    assert os.path.exists(moved_dir)

    # Close the workspace
    result = cli.run(project=moved_dir, args=["workspace", "close", "--remove-dir", element_name])
    result.assert_success()

    # Assert the workspace dir has been deleted
    assert not os.path.exists(workspace_dir)


@pytest.mark.datafiles(DATA_DIR)
def test_close_internal_after_move_project(cli, tmpdir, datafiles):
    initial_dir = os.path.join(str(tmpdir), "initial_project")
    initial_workspace = os.path.join(initial_dir, "workspace")
    element_name, _, _ = open_workspace(
        cli, tmpdir, datafiles, "git", workspace_dir=initial_workspace, project_path=initial_dir
    )
    moved_dir = os.path.join(str(tmpdir), "internal_project")
    shutil.move(initial_dir, moved_dir)
    assert os.path.exists(moved_dir)

    # Close the workspace
    result = cli.run(project=moved_dir, args=["workspace", "close", "--remove-dir", element_name])
    result.assert_success()

    # Assert the workspace dir has been deleted
    workspace = os.path.join(moved_dir, "workspace")
    assert not os.path.exists(workspace)


@pytest.mark.datafiles(DATA_DIR)
def test_close_removed(cli, tmpdir, datafiles):
    element_name, project, workspace = open_workspace(cli, tmpdir, datafiles, "git")

    # Remove it first, closing the workspace should work
    shutil.rmtree(workspace)

    # Close the workspace
    result = cli.run(project=project, args=["workspace", "close", element_name])
    result.assert_success()

    # Assert the workspace dir has been deleted
    assert not os.path.exists(workspace)


@pytest.mark.datafiles(DATA_DIR)
def test_close_nonexistant_element(cli, tmpdir, datafiles):
    element_name, project, workspace = open_workspace(cli, tmpdir, datafiles, "git")
    element_path = os.path.join(datafiles.dirname, datafiles.basename, "elements", element_name)

    # First brutally remove the element.bst file, ensuring that
    # the element does not exist anymore in the project where
    # we want to close the workspace.
    os.remove(element_path)

    # Close the workspace
    result = cli.run(project=project, args=["workspace", "close", "--remove-dir", element_name])
    result.assert_success()

    # Assert the workspace dir has been deleted
    assert not os.path.exists(workspace)


@pytest.mark.datafiles(DATA_DIR)
def test_close_multiple(cli, tmpdir, datafiles):
    tmpdir_alpha = os.path.join(str(tmpdir), "alpha")
    tmpdir_beta = os.path.join(str(tmpdir), "beta")
    alpha, project, workspace_alpha = open_workspace(cli, tmpdir_alpha, datafiles, "git", suffix="-alpha")
    beta, project, workspace_beta = open_workspace(cli, tmpdir_beta, datafiles, "git", suffix="-beta")

    # Close the workspaces
    result = cli.run(project=project, args=["workspace", "close", "--remove-dir", alpha, beta])
    result.assert_success()

    # Assert the workspace dirs have been deleted
    assert not os.path.exists(workspace_alpha)
    assert not os.path.exists(workspace_beta)


@pytest.mark.datafiles(DATA_DIR)
def test_close_all(cli, tmpdir, datafiles):
    tmpdir_alpha = os.path.join(str(tmpdir), "alpha")
    tmpdir_beta = os.path.join(str(tmpdir), "beta")
    _, project, workspace_alpha = open_workspace(cli, tmpdir_alpha, datafiles, "git", suffix="-alpha")
    _, project, workspace_beta = open_workspace(cli, tmpdir_beta, datafiles, "git", suffix="-beta")

    # Close the workspaces
    result = cli.run(project=project, args=["workspace", "close", "--remove-dir", "--all"])
    result.assert_success()

    # Assert the workspace dirs have been deleted
    assert not os.path.exists(workspace_alpha)
    assert not os.path.exists(workspace_beta)


@pytest.mark.datafiles(DATA_DIR)
def test_reset(cli, tmpdir, datafiles):
    # Open the workspace
    element_name, project, workspace = open_workspace(cli, tmpdir, datafiles, "git")

    # Modify workspace
    shutil.rmtree(os.path.join(workspace, "usr", "bin"))
    os.makedirs(os.path.join(workspace, "etc"))
    with open(os.path.join(workspace, "etc", "pony.conf"), "w", encoding="utf-8") as f:
        f.write("PONY='pink'")

    # Now reset the open workspace, this should have the
    # effect of reverting our changes.
    result = cli.run(project=project, args=["workspace", "reset", element_name])
    result.assert_success()
    assert os.path.exists(os.path.join(workspace, "usr", "bin", "hello"))
    assert not os.path.exists(os.path.join(workspace, "etc", "pony.conf"))


@pytest.mark.datafiles(DATA_DIR)
def test_reset_soft(cli, tmpdir, datafiles):
    # Open the workspace
    element_name, project, workspace = open_workspace(cli, tmpdir, datafiles, "git")

    assert cli.get_element_state(project, element_name) == "buildable"

    hello_path = os.path.join(workspace, "usr", "bin", "hello")
    pony_path = os.path.join(workspace, "etc", "pony.conf")

    assert os.path.exists(os.path.join(workspace, "usr", "bin"))
    assert os.path.exists(hello_path)
    assert not os.path.exists(pony_path)

    key_1 = cli.get_element_key(project, element_name)
    assert key_1 != "{:?<64}".format("")
    result = cli.run(project=project, args=["build", element_name])
    result.assert_success()
    assert cli.get_element_state(project, element_name) == "cached"
    key_2 = cli.get_element_key(project, element_name)
    assert key_2 != "{:?<64}".format("")

    # workspace keys are not recalculated
    assert key_1 == key_2

    wait_for_cache_granularity()

    # Modify workspace
    shutil.rmtree(os.path.join(workspace, "usr", "bin"))
    os.makedirs(os.path.join(workspace, "etc"))
    with open(os.path.join(workspace, "etc", "pony.conf"), "w", encoding="utf-8") as f:
        f.write("PONY='pink'")

    assert not os.path.exists(os.path.join(workspace, "usr", "bin"))
    assert os.path.exists(pony_path)

    # Now soft-reset the open workspace, this should not revert the changes
    result = cli.run(project=project, args=["workspace", "reset", "--soft", element_name])
    result.assert_success()
    # we removed this dir
    assert not os.path.exists(os.path.join(workspace, "usr", "bin"))
    # and added this one
    assert os.path.exists(os.path.join(workspace, "etc", "pony.conf"))

    assert cli.get_element_state(project, element_name) == "buildable"
    key_3 = cli.get_element_key(project, element_name)
    assert key_3 != "{:?<64}".format("")
    assert key_1 != key_3


@pytest.mark.datafiles(DATA_DIR)
def test_reset_multiple(cli, tmpdir, datafiles):
    # Open the workspaces
    tmpdir_alpha = os.path.join(str(tmpdir), "alpha")
    tmpdir_beta = os.path.join(str(tmpdir), "beta")
    alpha, project, workspace_alpha = open_workspace(cli, tmpdir_alpha, datafiles, "git", suffix="-alpha")
    beta, project, workspace_beta = open_workspace(cli, tmpdir_beta, datafiles, "git", suffix="-beta")

    # Modify workspaces
    shutil.rmtree(os.path.join(workspace_alpha, "usr", "bin"))
    os.makedirs(os.path.join(workspace_beta, "etc"))
    with open(os.path.join(workspace_beta, "etc", "pony.conf"), "w", encoding="utf-8") as f:
        f.write("PONY='pink'")

    # Now reset the open workspaces, this should have the
    # effect of reverting our changes.
    result = cli.run(project=project, args=["workspace", "reset", alpha, beta,])
    result.assert_success()
    assert os.path.exists(os.path.join(workspace_alpha, "usr", "bin", "hello"))
    assert not os.path.exists(os.path.join(workspace_beta, "etc", "pony.conf"))


@pytest.mark.datafiles(DATA_DIR)
def test_reset_all(cli, tmpdir, datafiles):
    # Open the workspaces
    tmpdir_alpha = os.path.join(str(tmpdir), "alpha")
    tmpdir_beta = os.path.join(str(tmpdir), "beta")
    _, project, workspace_alpha = open_workspace(cli, tmpdir_alpha, datafiles, "git", suffix="-alpha")
    _, project, workspace_beta = open_workspace(cli, tmpdir_beta, datafiles, "git", suffix="-beta")

    # Modify workspaces
    shutil.rmtree(os.path.join(workspace_alpha, "usr", "bin"))
    os.makedirs(os.path.join(workspace_beta, "etc"))
    with open(os.path.join(workspace_beta, "etc", "pony.conf"), "w", encoding="utf-8") as f:
        f.write("PONY='pink'")

    # Now reset the open workspace, this should have the
    # effect of reverting our changes.
    result = cli.run(project=project, args=["workspace", "reset", "--all"])
    result.assert_success()
    assert os.path.exists(os.path.join(workspace_alpha, "usr", "bin", "hello"))
    assert not os.path.exists(os.path.join(workspace_beta, "etc", "pony.conf"))


@pytest.mark.datafiles(DATA_DIR)
def test_list(cli, tmpdir, datafiles):
    element_name, project, workspace = open_workspace(cli, tmpdir, datafiles, "git")

    # Now list the workspaces
    result = cli.run(project=project, args=["workspace", "list"])
    result.assert_success()

    loaded = _yaml.load_data(result.output)
    workspaces = loaded.get_sequence("workspaces")
    assert len(workspaces) == 1

    space = workspaces.mapping_at(0)
    assert space.get_str("element") == element_name
    assert space.get_str("directory") == workspace


@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.parametrize("kind", repo_kinds)
@pytest.mark.parametrize("strict", [("strict"), ("non-strict")])
@pytest.mark.parametrize(
    "from_workspace,guess_element",
    [(False, False), (True, True), (True, False)],
    ids=["project-no-guess", "workspace-guess", "workspace-no-guess"],
)
def test_build(cli, tmpdir_factory, datafiles, kind, strict, from_workspace, guess_element):
    tmpdir = tmpdir_factory.mktemp(BASE_FILENAME)
    element_name, project, workspace = open_workspace(cli, tmpdir, datafiles, kind, False)
    checkout = os.path.join(str(tmpdir), "checkout")
    args_dir = ["-C", workspace] if from_workspace else []
    args_elm = [element_name] if not guess_element else []

    # Modify workspace
    shutil.rmtree(os.path.join(workspace, "usr", "bin"))
    os.makedirs(os.path.join(workspace, "etc"))
    with open(os.path.join(workspace, "etc", "pony.conf"), "w", encoding="utf-8") as f:
        f.write("PONY='pink'")

    # Configure strict mode
    strict_mode = True
    if strict != "strict":
        strict_mode = False
    cli.configure({"projects": {"test": {"strict": strict_mode}}})

    # Build modified workspace
    assert cli.get_element_state(project, element_name) == "buildable"
    key_1 = cli.get_element_key(project, element_name)
    assert key_1 != "{:?<64}".format("")
    result = cli.run(project=project, args=args_dir + ["build", *args_elm])
    result.assert_success()
    assert cli.get_element_state(project, element_name) == "cached"
    key_2 = cli.get_element_key(project, element_name)
    assert key_2 != "{:?<64}".format("")

    # workspace keys are not recalculated
    assert key_1 == key_2

    # Checkout the result
    result = cli.run(project=project, args=args_dir + ["artifact", "checkout", "--directory", checkout, *args_elm])
    result.assert_success()

    # Check that the pony.conf from the modified workspace exists
    filename = os.path.join(checkout, "etc", "pony.conf")
    assert os.path.exists(filename)

    # Check that the original /usr/bin/hello is not in the checkout
    assert not os.path.exists(os.path.join(checkout, "usr", "bin", "hello"))


@pytest.mark.datafiles(DATA_DIR)
def test_buildable_no_ref(cli, tmpdir, datafiles):
    project = str(datafiles)
    element_name = "workspace-test-no-ref.bst"
    element_path = os.path.join(project, "elements")

    # Write out our test target without any source ref
    repo = create_repo("git", str(tmpdir))
    element = {"kind": "import", "sources": [repo.source_config()]}
    _yaml.roundtrip_dump(element, os.path.join(element_path, element_name))

    # Assert that this target is not buildable when no workspace is associated.
    assert cli.get_element_state(project, element_name) == "no reference"

    # Now open the workspace. We don't need to checkout the source though.
    workspace = os.path.join(str(tmpdir), "workspace-no-ref")
    os.makedirs(workspace)
    args = ["workspace", "open", "--no-checkout", "--directory", workspace, element_name]
    result = cli.run(project=project, args=args)
    result.assert_success()

    # Assert that the target is now buildable.
    assert cli.get_element_state(project, element_name) == "buildable"


@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.parametrize("modification", [("addfile"), ("removefile"), ("modifyfile")])
@pytest.mark.parametrize("strict", [("strict"), ("non-strict")])
def test_detect_modifications(cli, tmpdir, datafiles, modification, strict):
    element_name, project, workspace = open_workspace(cli, tmpdir, datafiles, "git")
    checkout = os.path.join(str(tmpdir), "checkout")

    # Configure strict mode
    strict_mode = True
    if strict != "strict":
        strict_mode = False
    cli.configure({"projects": {"test": {"strict": strict_mode}}})

    # Build clean workspace
    assert cli.get_element_state(project, element_name) == "buildable"
    key_1 = cli.get_element_key(project, element_name)
    assert key_1 != "{:?<64}".format("")
    result = cli.run(project=project, args=["build", element_name])
    result.assert_success()
    assert cli.get_element_state(project, element_name) == "cached"
    key_2 = cli.get_element_key(project, element_name)
    assert key_2 != "{:?<64}".format("")

    # workspace keys are not recalculated
    assert key_1 == key_2

    wait_for_cache_granularity()

    # Modify the workspace in various different ways, ensuring we
    # properly detect the changes.
    #
    if modification == "addfile":
        os.makedirs(os.path.join(workspace, "etc"))
        with open(os.path.join(workspace, "etc", "pony.conf"), "w", encoding="utf-8") as f:
            f.write("PONY='pink'")
    elif modification == "removefile":
        os.remove(os.path.join(workspace, "usr", "bin", "hello"))
    elif modification == "modifyfile":
        with open(os.path.join(workspace, "usr", "bin", "hello"), "w", encoding="utf-8") as f:
            f.write("cookie")
    else:
        # This cannot be reached
        assert 0

    # First assert that the state is properly detected
    assert cli.get_element_state(project, element_name) == "buildable"
    key_3 = cli.get_element_key(project, element_name)
    assert key_3 != "{:?<64}".format("")

    # Since there are different things going on at `bst build` time
    # than `bst show` time, we also want to build / checkout again,
    # and ensure that the result contains what we expect.
    result = cli.run(project=project, args=["build", element_name])
    result.assert_success()
    assert cli.get_element_state(project, element_name) == "cached"
    key_4 = cli.get_element_key(project, element_name)
    assert key_4 != "{:?<64}".format("")

    # workspace keys are not recalculated
    assert key_3 == key_4
    # workspace keys are determined by the files
    assert key_1 != key_3

    # Checkout the result
    result = cli.run(project=project, args=["artifact", "checkout", element_name, "--directory", checkout])
    result.assert_success()

    # Check the result for the changes we made
    #
    if modification == "addfile":
        filename = os.path.join(checkout, "etc", "pony.conf")
        assert os.path.exists(filename)
    elif modification == "removefile":
        assert not os.path.exists(os.path.join(checkout, "usr", "bin", "hello"))
    elif modification == "modifyfile":
        with open(os.path.join(workspace, "usr", "bin", "hello"), "r", encoding="utf-8") as f:
            data = f.read()
            assert data == "cookie"
    else:
        # This cannot be reached
        assert 0


# Ensure that various versions that should not be accepted raise a
# LoadError.INVALID_DATA
@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.parametrize(
    "workspace_cfg",
    [
        # Test loading a negative workspace version
        {"format-version": -1},
        # Test loading version 0 with two sources
        {"format-version": 0, "alpha.bst": {0: "/workspaces/bravo", 1: "/workspaces/charlie",}},
        # Test loading a version with decimals
        {"format-version": 0.5},
        # Test loading an unsupported old version
        {"format-version": 3},
        # Test loading a future version
        {"format-version": BST_WORKSPACE_FORMAT_VERSION + 1},
    ],
)
def test_list_unsupported_workspace(cli, datafiles, workspace_cfg):
    project = str(datafiles)
    os.makedirs(os.path.join(project, ".bst2"))
    workspace_config_path = os.path.join(project, ".bst2", "workspaces.yml")

    _yaml.roundtrip_dump(workspace_cfg, workspace_config_path)

    result = cli.run(project=project, args=["workspace", "list"])
    result.assert_main_error(ErrorDomain.LOAD, LoadErrorReason.INVALID_DATA)


# Ensure that various versions that should be accepted are parsed
# correctly.
@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.parametrize(
    "workspace_cfg,expected",
    [
        # Test loading version 4
        (
            {"format-version": 4, "workspaces": {"alpha.bst": {"path": "/workspaces/bravo"}},},
            {
                "format-version": BST_WORKSPACE_FORMAT_VERSION,
                "workspaces": {"alpha.bst": {"path": "/workspaces/bravo"}},
            },
        ),
    ],
)
def test_list_supported_workspace(cli, tmpdir, datafiles, workspace_cfg, expected):
    def parse_dict_as_yaml(node):
        tempfile = os.path.join(str(tmpdir), "yaml_dump")
        _yaml.roundtrip_dump(node, tempfile)
        return _yaml.load(tempfile, shortname=None).strip_node_info()

    project = str(datafiles)
    os.makedirs(os.path.join(project, ".bst"))
    workspace_config_path = os.path.join(project, ".bst", "workspaces.yml")

    _yaml.roundtrip_dump(workspace_cfg, workspace_config_path)

    # Check that we can still read workspace config that is in old format
    result = cli.run(project=project, args=["workspace", "list"])
    result.assert_success()

    loaded_config = _yaml.load(workspace_config_path, shortname=None).strip_node_info()

    # Check that workspace config remains the same if no modifications
    # to workspaces were made
    assert loaded_config == parse_dict_as_yaml(workspace_cfg)

    # Create a test bst file
    bin_files_path = os.path.join(project, "files", "bin-files")
    element_path = os.path.join(project, "elements")
    element_name = "workspace-test.bst"
    workspace = os.path.join(str(tmpdir), "workspace")

    # Create our repo object of the given source type with
    # the bin files, and then collect the initial ref.
    #
    repo = create_repo("git", str(tmpdir))
    ref = repo.create(bin_files_path)

    # Write out our test target
    element = {"kind": "import", "sources": [repo.source_config(ref=ref)]}
    _yaml.roundtrip_dump(element, os.path.join(element_path, element_name))

    # Make a change to the workspaces file
    result = cli.run(project=project, args=["workspace", "open", "--directory", workspace, element_name])
    result.assert_success()
    result = cli.run(project=project, args=["workspace", "close", "--remove-dir", element_name])
    result.assert_success()

    # Check that workspace config is converted correctly if necessary
    loaded_config = _yaml.load(workspace_config_path, shortname=None).strip_node_info()
    assert loaded_config == parse_dict_as_yaml(expected)


@pytest.mark.datafiles(DATA_DIR)
def test_inconsitent_pipeline_message(cli, tmpdir, datafiles):
    element_name, project, workspace = open_workspace(cli, tmpdir, datafiles, "git")

    shutil.rmtree(workspace)

    result = cli.run(project=project, args=["build", element_name])
    result.assert_main_error(ErrorDomain.PIPELINE, "inconsistent-pipeline-workspaced")


@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.parametrize("strict", [("strict"), ("non-strict")])
def test_cache_key_workspace_in_dependencies(cli, tmpdir, datafiles, strict):
    checkout = os.path.join(str(tmpdir), "checkout")
    element_name, project, workspace = open_workspace(cli, os.path.join(str(tmpdir), "repo-a"), datafiles, "git")

    element_path = os.path.join(project, "elements")
    back_dep_element_name = "workspace-test-back-dep.bst"

    # Write out our test target
    element = {"kind": "compose", "depends": [{"filename": element_name, "type": "build"}]}
    _yaml.roundtrip_dump(element, os.path.join(element_path, back_dep_element_name))

    # Modify workspace
    shutil.rmtree(os.path.join(workspace, "usr", "bin"))
    os.makedirs(os.path.join(workspace, "etc"))
    with open(os.path.join(workspace, "etc", "pony.conf"), "w", encoding="utf-8") as f:
        f.write("PONY='pink'")

    # Configure strict mode
    strict_mode = True
    if strict != "strict":
        strict_mode = False
    cli.configure({"projects": {"test": {"strict": strict_mode}}})

    # Build artifact with dependency's modified workspace
    assert cli.get_element_state(project, element_name) == "buildable"
    key_a1 = cli.get_element_key(project, element_name)
    assert key_a1 != "{:?<64}".format("")
    assert cli.get_element_state(project, back_dep_element_name) == "waiting"
    key_b1 = cli.get_element_key(project, back_dep_element_name)
    assert key_b1 != "{:?<64}".format("")
    result = cli.run(project=project, args=["build", back_dep_element_name])
    result.assert_success()
    assert cli.get_element_state(project, element_name) == "cached"
    key_a2 = cli.get_element_key(project, element_name)
    assert key_a2 != "{:?<64}".format("")
    assert cli.get_element_state(project, back_dep_element_name) == "cached"
    key_b2 = cli.get_element_key(project, back_dep_element_name)
    assert key_b2 != "{:?<64}".format("")
    result = cli.run(project=project, args=["build", back_dep_element_name])
    result.assert_success()

    # workspace keys are not recalculated
    assert key_a1 == key_a2
    assert key_b1 == key_b2

    # Checkout the result
    result = cli.run(project=project, args=["artifact", "checkout", back_dep_element_name, "--directory", checkout])
    result.assert_success()

    # Check that the pony.conf from the modified workspace exists
    filename = os.path.join(checkout, "etc", "pony.conf")
    assert os.path.exists(filename)

    # Check that the original /usr/bin/hello is not in the checkout
    assert not os.path.exists(os.path.join(checkout, "usr", "bin", "hello"))


@pytest.mark.datafiles(DATA_DIR)
def test_multiple_failed_builds(cli, tmpdir, datafiles):
    element_config = {"kind": "manual", "config": {"configure-commands": ["unknown_command_that_will_fail"]}}
    element_name, project, _ = open_workspace(cli, tmpdir, datafiles, "git", element_attrs=element_config)

    for _ in range(2):
        result = cli.run(project=project, args=["build", element_name])
        assert "BUG" not in result.stderr
        assert cli.get_element_state(project, element_name) != "cached"


@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.parametrize("subdir", [True, False], ids=["subdir", "no-subdir"])
@pytest.mark.parametrize("guess_element", [True, False], ids=["guess", "no-guess"])
def test_external_fetch(cli, datafiles, tmpdir_factory, subdir, guess_element):
    # An element with an open workspace can't be fetched, but we still expect fetches
    # to fetch any dependencies
    tmpdir = tmpdir_factory.mktemp(BASE_FILENAME)
    depend_element = "fetchable.bst"

    # Create an element to fetch (local sources do not need to fetch)
    create_element_size(depend_element, str(datafiles), "elements", [], 1024)

    element_name, project, workspace = open_workspace(
        cli, tmpdir, datafiles, "git", no_checkout=True, element_attrs={"depends": [depend_element]}
    )
    arg_elm = [element_name] if not guess_element else []

    if subdir:
        call_dir = os.path.join(workspace, "usr")
        os.makedirs(call_dir, exist_ok=True)
    else:
        call_dir = workspace

    # Assert that the depended element is not fetched yet
    assert cli.get_element_state(str(datafiles), depend_element) == "fetch needed"

    # Fetch the workspaced element
    result = cli.run(project=project, args=["-C", call_dir, "source", "fetch", "--deps", "all", *arg_elm])
    result.assert_success()

    # Assert that the depended element has now been fetched
    assert cli.get_element_state(str(datafiles), depend_element) == "buildable"


@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.parametrize("guess_element", [True, False], ids=["guess", "no-guess"])
def test_external_push_pull(cli, datafiles, tmpdir_factory, guess_element):
    # Pushing and pulling to/from an artifact cache works from an external workspace
    tmpdir = tmpdir_factory.mktemp(BASE_FILENAME)
    element_name, project, workspace = open_workspace(cli, tmpdir, datafiles, "git")
    arg_elm = [element_name] if not guess_element else []

    with create_artifact_share(os.path.join(str(tmpdir), "artifactshare")) as share:
        result = cli.run(project=project, args=["-C", workspace, "build", element_name])
        result.assert_success()

        cli.configure({"artifacts": {"servers": [{"url": share.repo, "push": True}]}})

        result = cli.run(project=project, args=["-C", workspace, "artifact", "push", *arg_elm])
        result.assert_success()

        result = cli.run(project=project, args=["-C", workspace, "artifact", "pull", "--deps", "all", *arg_elm])
        result.assert_success()


# Attempting to track in an open workspace is not a sensible thing and it's not compatible with workspaces as plugin
# sources: The new ref (if it differed from the old) would have been ignored regardless.
# The user should be expected to simply close the workspace before tracking.
@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.parametrize("guess_element", [True, False], ids=["guess", "no-guess"])
def test_external_track(cli, datafiles, tmpdir_factory, guess_element):
    tmpdir = tmpdir_factory.mktemp(BASE_FILENAME)
    element_name, project, workspace = open_workspace(cli, tmpdir, datafiles, "git")
    element_file = os.path.join(str(datafiles), "elements", element_name)
    arg_elm = [element_name] if not guess_element else []

    # Delete the ref from the source so that we can detect if the
    # element has been tracked after closing the workspace
    element_contents = _yaml.load(element_file, shortname=None)
    ref1 = element_contents.get_sequence("sources").mapping_at(0).get_str("ref")
    del element_contents.get_sequence("sources").mapping_at(0)["ref"]
    _yaml.roundtrip_dump(element_contents, element_file)

    result = cli.run(project=project, args=["-C", workspace, "source", "track", *arg_elm])
    result.assert_success()

    # Element is not tracked now
    element_contents = _yaml.load(element_file, shortname=None)
    assert "ref" not in element_contents.get_sequence("sources").mapping_at(0)

    # close the workspace
    result = cli.run(project=project, args=["-C", workspace, "workspace", "close", *arg_elm])
    result.assert_success()

    # and retrack the element
    result = cli.run(project=project, args=["source", "track", element_name])
    result.assert_success()

    element_contents = _yaml.load(element_file, shortname=None)
    ref2 = element_contents.get_sequence("sources").mapping_at(0).get_str("ref")
    # these values should be equivalent
    assert ref1 == ref2


@pytest.mark.datafiles(DATA_DIR)
def test_external_open_other(cli, datafiles, tmpdir_factory):
    # From inside an external workspace, open another workspace
    tmpdir1 = tmpdir_factory.mktemp(BASE_FILENAME)
    tmpdir2 = tmpdir_factory.mktemp(BASE_FILENAME)
    # Making use of the assumption that it's the same project in both invocations of open_workspace
    _, project, alpha_workspace = open_workspace(cli, tmpdir1, datafiles, "git", suffix="-alpha")
    beta_element, _, beta_workspace = open_workspace(cli, tmpdir2, datafiles, "git", suffix="-beta")

    # Closing the other element first, because I'm too lazy to create an
    # element without opening it
    result = cli.run(project=project, args=["workspace", "close", beta_element])
    result.assert_success()

    result = cli.run(
        project=project,
        args=["-C", alpha_workspace, "workspace", "open", "--force", "--directory", beta_workspace, beta_element],
    )
    result.assert_success()


@pytest.mark.datafiles(DATA_DIR)
def test_external_reset_other(cli, datafiles, tmpdir_factory):
    tmpdir1 = tmpdir_factory.mktemp(BASE_FILENAME)
    tmpdir2 = tmpdir_factory.mktemp(BASE_FILENAME)
    # Making use of the assumption that it's the same project in both invocations of open_workspace
    _, project, alpha_workspace = open_workspace(cli, tmpdir1, datafiles, "git", suffix="-alpha")
    beta_element, _, _ = open_workspace(cli, tmpdir2, datafiles, "git", suffix="-beta")

    result = cli.run(project=project, args=["-C", alpha_workspace, "workspace", "reset", beta_element])
    result.assert_success()


@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.parametrize("guess_element", [True, False], ids=["guess", "no-guess"])
def test_external_reset_self(cli, datafiles, tmpdir, guess_element):
    element, project, workspace = open_workspace(cli, tmpdir, datafiles, "git")
    arg_elm = [element] if not guess_element else []

    # Command succeeds
    result = cli.run(project=project, args=["-C", workspace, "workspace", "reset", *arg_elm])
    result.assert_success()

    # Successive commands still work (i.e. .bstproject.yaml hasn't been deleted)
    result = cli.run(project=project, args=["-C", workspace, "workspace", "list"])
    result.assert_success()


@pytest.mark.datafiles(DATA_DIR)
def test_external_list(cli, datafiles, tmpdir_factory):
    tmpdir = tmpdir_factory.mktemp(BASE_FILENAME)
    # Making use of the assumption that it's the same project in both invocations of open_workspace
    _, project, workspace = open_workspace(cli, tmpdir, datafiles, "git")

    result = cli.run(project=project, args=["-C", workspace, "workspace", "list"])
    result.assert_success()


@pytest.mark.datafiles(DATA_DIR)
def test_multisource_workspace(cli, datafiles, tmpdir):
    # checks that if an element has multiple sources, then the opened workspace
    # will contain them
    project = str(datafiles)
    element_name = "multisource.bst"
    element = {
        "kind": "import",
        "sources": [{"kind": "local", "path": "files/bin-files"}, {"kind": "local", "path": "files/dev-files"}],
    }
    element_path = os.path.join(project, "elements", element_name)
    _yaml.roundtrip_dump(element, element_path)

    workspace_dir = os.path.join(str(tmpdir), "multisource")
    res = cli.run(project=project, args=["workspace", "open", "multisource.bst", "--directory", workspace_dir])
    res.assert_success()

    directories = os.listdir(os.path.join(workspace_dir, "usr"))
    assert "bin" in directories and "include" in directories


# This strange test tests against a regression raised in issue #919,
# where opening a workspace on a runtime dependency of a build only
# dependency causes `bst build` to not build the specified target
# but just successfully builds the workspaced element and happily
# exits without completing the build.
#
TEST_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)))


@pytest.mark.datafiles(TEST_DIR)
@pytest.mark.parametrize(
    ["case", "non_workspaced_elements_state"],
    [
        ("workspaced-build-dep", ["waiting", "waiting", "waiting", "waiting", "waiting"]),
        ("workspaced-runtime-dep", ["buildable", "buildable", "waiting", "waiting", "waiting"]),
    ],
)
@pytest.mark.parametrize("strict", [("strict"), ("non-strict")])
def test_build_all(cli, tmpdir, datafiles, case, strict, non_workspaced_elements_state):
    project = os.path.join(str(datafiles), case)
    workspace = os.path.join(str(tmpdir), "workspace")
    non_leaf_elements = ["elem2.bst", "elem3.bst", "stack.bst", "elem4.bst", "elem5.bst"]
    all_elements = ["elem1.bst", *non_leaf_elements]

    # Configure strict mode
    strict_mode = True
    if strict != "strict":
        strict_mode = False
    cli.configure({"projects": {"test": {"strict": strict_mode}}})

    # First open the workspace
    result = cli.run(project=project, args=["workspace", "open", "--directory", workspace, "elem1.bst"])
    result.assert_success()

    # Ensure all elements are waiting build the first
    assert cli.get_element_states(project, all_elements) == dict(
        zip(all_elements, ["buildable", *non_workspaced_elements_state])
    )

    # Now build the targets elem4.bst and elem5.bst
    result = cli.run(project=project, args=["build", "elem4.bst", "elem5.bst"])
    result.assert_success()

    # Assert that the target is built
    assert cli.get_element_states(project, all_elements) == {elem: "cached" for elem in all_elements}


@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.parametrize("strict", ["strict", "non-strict"])
def test_show_workspace_logs(cli, tmpdir, datafiles, strict):
    project = str(datafiles)
    workspace = os.path.join(str(tmpdir), "workspace")
    target = "manual.bst"

    # Configure strict mode
    strict_mode = True
    if strict != "strict":
        strict_mode = False
    cli.configure({"projects": {"test": {"strict": strict_mode}}})

    # First open the workspace
    result = cli.run(project=project, args=["workspace", "open", "--directory", workspace, target])
    result.assert_success()

    # Build the element
    result = cli.run(project=project, args=["build", target])
    result.assert_task_error(ErrorDomain.SANDBOX, "missing-command")

    result = cli.run(project=project, args=["artifact", "log", target])
    result.assert_success()

    # Assert that the log is not empty
    assert result.output != ""
