# 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, "shell-missing-deps"),
        # 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),
    ],
    ids=["no-pull", "pull-only-deps", "pull-without-buildtree", "pull-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")
