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

import os
import shutil

import pytest

from buildstream._testing import cli, cli_integration, Cli  # pylint: disable=unused-import
from buildstream.exceptions import ErrorDomain
from buildstream._testing._utils.site import HAVE_SANDBOX

from tests.testutils import ArtifactShare


pytestmark = pytest.mark.integration


DATA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "project")


#
# Ensure that we didn't get a build tree if we didn't ask for one
#
@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.skipif(not HAVE_SANDBOX, reason="Only available with a functioning sandbox")
def test_buildtree_unused(cli_integration, datafiles):
    # We can only test the non interacitve case
    # The non interactive case defaults to not using buildtrees
    # for `bst shell --build`
    project = str(datafiles)
    element_name = "build-shell/buildtree.bst"

    res = cli_integration.run(project=project, args=["--cache-buildtrees", "always", "build", element_name])
    res.assert_success()

    res = cli_integration.run(project=project, args=["shell", "--build", element_name, "--", "cat", "test"])
    res.assert_shell_error()


#
# Ensure we can use a buildtree from a successful build
#
@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.skipif(not HAVE_SANDBOX, reason="Only available with a functioning sandbox")
def test_buildtree_from_success(cli_integration, datafiles):
    # Test that if we ask for a build tree it is there.
    project = str(datafiles)
    element_name = "build-shell/buildtree.bst"

    res = cli_integration.run(project=project, args=["--cache-buildtrees", "always", "build", element_name])
    res.assert_success()

    res = cli_integration.run(
        project=project, args=["shell", "--build", "--use-buildtree", element_name, "--", "cat", "test"]
    )
    res.assert_success()
    assert "Hi" in res.output


#
# Ensure we can use a buildtree from a failed build
#
@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.skipif(not HAVE_SANDBOX, reason="Only available with a functioning sandbox")
def test_buildtree_from_failure(cli_integration, datafiles):
    # Test that we can use a build tree after a failure
    project = str(datafiles)
    element_name = "build-shell/buildtree-fail.bst"

    res = cli_integration.run(project=project, args=["build", element_name])
    res.assert_main_error(ErrorDomain.STREAM, None)

    # Assert that file has expected contents
    res = cli_integration.run(
        project=project, args=["shell", "--build", element_name, "--use-buildtree", "--", "cat", "test"]
    )
    res.assert_success()
    assert "WARNING using a buildtree from a failed build" in res.stderr
    assert "Hi" in res.output


###########################################################################
#                        Custom fixture ahead                             #
###########################################################################
#
# There are a lot of scenarios to test with launching shells with various states
# of local cache, which all require that artifacts be built in an artifact share.
#
# We want to use @pytest.mark.parametrize() here so that we can more coherently test
# specific scenarios, but testing each of these in a separate test is very expensive.
#
# For this reason, we use some module scope fixtures which will prepare the
# ArtifactShare() object by building and pushing to it, and the same ArtifactShare()
# object is shared across all tests which need the ArtifactShare() to be in that
# given state.
#
# This means we only need to download (fetch) the external alpine runtime and
# push it to our internal ArtifactShare() once, but we can reuse it for many
# parametrized tests.
#
# It is important that none of the tests using these fixtures access the
# module scope ArtifactShare() instances with "push" access, as tests
# should not be modifying the state of the shared data.
#
###########################################################################


# create_built_artifact_share()
#
# A helper function to create an ArtifactShare object with artifacts
# prebuilt, this can be shared across multiple tests which access
# the artifact share in a read-only fashion.
#
# Args:
#    tmpdir (str): The temp directory to be used
#    cache_buildtrees (bool): Whether to cache buildtrees when building
#    integration_cache (IntegrationCache): The session wide integration cache so that we
#                                          can reuse the sources from previous runs
#
def create_built_artifact_share(tmpdir, cache_buildtrees, integration_cache):
    element_name = "build-shell/buildtree.bst"

    # Replicate datafiles behavior and do work entirely in the temp directory
    project = os.path.join(tmpdir, "project")
    shutil.copytree(DATA_DIR, project)

    # Create the share to be hosted from this temp directory
    share = ArtifactShare(os.path.join(tmpdir, "artifactcache"))

    # Create a Cli instance to build and populate the share
    cli = Cli(os.path.join(tmpdir, "cache"))
    cli.configure(
        {"artifacts": {"servers": [{"url": share.repo, "push": True}]}, "sourcedir": integration_cache.sources}
    )

    # Optionally cache build trees
    args = []
    if cache_buildtrees:
        args += ["--cache-buildtrees", "always"]
    args += ["build", element_name]

    # Build
    result = cli.run(project=project, args=args)
    result.assert_success()

    # Assert that the artifact is indeed in the share
    assert cli.get_element_state(project, element_name) == "cached"
    artifact_name = cli.get_artifact_name(project, "test", element_name)
    assert share.get_artifact(artifact_name)

    return share


# share_with_buildtrees()
#
# A module scope fixture which prepares an ArtifactShare() instance
# which will have all dependencies of "build-shell/buildtree.bst" built and
# cached with buildtrees also cached.
#
@pytest.fixture(scope="module")
def share_with_buildtrees(tmp_path_factory, integration_cache):
    # Get a temporary directory for this module scope fixture
    tmpdir = tmp_path_factory.mktemp("artifact_share_with_buildtrees")

    # Create our ArtifactShare instance which will persist for the duration of
    # the class scope fixture.
    share = create_built_artifact_share(tmpdir, True, integration_cache)
    try:
        yield share
    finally:
        share.close()


# share_without_buildtrees()
#
# A module scope fixture which prepares an ArtifactShare() instance
# which will have all dependencies of "build-shell/buildtree.bst" built
# but without caching any buildtrees.
#
@pytest.fixture(scope="module")
def share_without_buildtrees(tmp_path_factory, integration_cache):
    # Get a temporary directory for this module scope fixture
    tmpdir = tmp_path_factory.mktemp("artifact_share_without_buildtrees")

    # Create our ArtifactShare instance which will persist for the duration of
    # the class scope fixture.
    share = create_built_artifact_share(tmpdir, False, integration_cache)
    try:
        yield share
    finally:
        share.close()


# maybe_pull_deps()
#
# Convenience function for optionally pulling element dependencies
# in the following parametrized tests.
#
# Args:
#    cli (Cli): The Cli object
#    project (str): The project path
#    element_name (str): The element name
#    pull_deps (str): The argument for `--deps`, or None
#    pull_buildtree (bool): Whether to also pull buildtrees
#
def maybe_pull_deps(cli, project, element_name, pull_deps, pull_buildtree):

    # Optionally pull the buildtree along with `bst artifact pull`
    if pull_deps:
        args = []
        if pull_buildtree:
            args += ["--pull-buildtrees"]
        args += ["artifact", "pull", "--deps", pull_deps, element_name]

        # Pull from cache
        result = cli.run(project=project, args=args)
        result.assert_success()


#
# Test behavior of launching a shell and requesting to use a buildtree, with
# various states of local cache (ranging from nothing cached to everything cached)
#
@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.skipif(not HAVE_SANDBOX, reason="Only available with a functioning sandbox")
@pytest.mark.parametrize(
    "pull_deps,pull_buildtree,expect_error",
    [
        # Don't pull at all
        (None, False, "missing-buildtree-artifact-not-cached"),
        # Pull only dependencies
        ("build", False, "missing-buildtree-artifact-not-cached"),
        # Pull all elements including the shell element, but without the buildtree
        ("all", False, "missing-buildtree-artifact-buildtree-not-cached"),
        # Pull all elements including the shell element, and pull buildtrees
        ("all", True, None),
        # Pull only the artifact, but without the buildtree
        ("none", False, "missing-buildtree-artifact-buildtree-not-cached"),
        # Pull only the artifact with its buildtree
        ("none", True, None),
    ],
    ids=[
        "no-pull",
        "pull-only-deps",
        "pull-without-buildtree",
        "pull-with-buildtree",
        "pull-target-without-buildtree",
        "pull-target-with-buildtree",
    ],
)
def test_shell_use_cached_buildtree(share_with_buildtrees, datafiles, cli, pull_deps, pull_buildtree, expect_error):
    project = str(datafiles)
    element_name = "build-shell/buildtree.bst"

    cli.configure({"artifacts": {"servers": [{"url": share_with_buildtrees.repo}]}})

    # Optionally pull the buildtree along with `bst artifact pull`
    maybe_pull_deps(cli, project, element_name, pull_deps, pull_buildtree)

    # Disable access to the artifact server after pulling, so that `bst shell` cannot automatically
    # pull the missing bits, this should be equivalent to the missing bits being missing in a
    # remote server
    cli.configure({"artifacts": {}})

    # Run the shell without asking it to pull any buildtree, just asking to use a buildtree
    result = cli.run(project=project, args=["shell", "--build", element_name, "--use-buildtree", "--", "cat", "test"])

    if expect_error:
        result.assert_main_error(ErrorDomain.APP, expect_error)
    else:
        result.assert_success()
        assert "Hi" in result.output


#
# Test behavior of launching a shell and requesting to use a buildtree, while allowing
# BuildStream to download any missing bits from the artifact server on the fly (which
# it will do by default) again with various states of local cache (ranging from nothing
# cached to everything cached)
#
@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.skipif(not HAVE_SANDBOX, reason="Only available with a functioning sandbox")
@pytest.mark.parametrize(
    "pull_deps,pull_buildtree",
    [
        # Don't pull at all
        (None, False),
        # Pull only dependencies
        ("build", False),
        # Pull all elements including the shell element, but without the buildtree
        ("all", False),
        # Pull all elements including the shell element, and pull buildtrees
        ("all", True),
    ],
    ids=["no-pull", "pull-only-deps", "pull-without-buildtree", "pull-with-buildtree"],
)
def test_shell_pull_cached_buildtree(share_with_buildtrees, datafiles, cli, pull_deps, pull_buildtree):
    project = str(datafiles)
    element_name = "build-shell/buildtree.bst"

    cli.configure({"artifacts": {"servers": [{"url": share_with_buildtrees.repo}]}})

    # Optionally pull the buildtree along with `bst artifact pull`
    maybe_pull_deps(cli, project, element_name, pull_deps, pull_buildtree)

    # Run the shell and request that required artifacts and buildtrees should be pulled
    result = cli.run(
        project=project,
        args=[
            "--pull-buildtrees",
            "shell",
            "--build",
            element_name,
            "--use-buildtree",
            "--",
            "cat",
            "test",
        ],
    )

    # In this case, we should succeed every time, regardless of what was
    # originally available in the local cache.
    #
    result.assert_success()
    assert "Hi" in result.output


#
# Test behavior of launching a shell and requesting to use a buildtree.
#
# In this case we download everything we need first, but the buildtree was never cached at build time
#
@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.skipif(not HAVE_SANDBOX, reason="Only available with a functioning sandbox")
def test_shell_use_uncached_buildtree(share_without_buildtrees, datafiles, cli):
    project = str(datafiles)
    element_name = "build-shell/buildtree.bst"

    cli.configure({"artifacts": {"servers": [{"url": share_without_buildtrees.repo}]}})

    # Pull everything we would need
    maybe_pull_deps(cli, project, element_name, "all", True)

    # Run the shell without asking it to pull any buildtree, just asking to use a buildtree
    result = cli.run(project=project, args=["shell", "--build", element_name, "--use-buildtree", "--", "cat", "test"])

    # Sorry, a buildtree was never cached for this element
    result.assert_main_error(ErrorDomain.APP, "missing-buildtree-artifact-created-without-buildtree")


@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.skipif(not HAVE_SANDBOX, reason="Only available with a functioning sandbox")
def test_shell_script_element(datafiles, cli_integration):
    project = str(datafiles)
    element_name = "build-shell/script.bst"

    result = cli_integration.run(project=project, args=["--cache-buildtrees", "always", "build", element_name])
    result.assert_success()

    # Run the shell and use the cached buildtree on this script element
    result = cli_integration.run(
        project=project, args=["shell", "--build", element_name, "--use-buildtree", "--", "cat", "/test"]
    )

    result.assert_success()
    assert "Hi" in result.output
