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

import os

import pytest

from buildstream import _yaml
from buildstream._testing import cli  # pylint: disable=unused-import
from buildstream.exceptions import ErrorDomain, LoadErrorReason


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

#
# Test links to elements, this tests both specifying the link as
# the main target, and also as a dependency of the main target.
#
@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.parametrize("target", ["target.bst", "hello-link.bst"])
def test_simple_link(cli, tmpdir, datafiles, target):
    project = os.path.join(str(datafiles), "simple")
    checkoutdir = os.path.join(str(tmpdir), "checkout")

    # Build, checkout
    result = cli.run(project=project, args=["build", target])
    result.assert_success()
    result = cli.run(project=project, args=["artifact", "checkout", target, "--directory", checkoutdir])
    result.assert_success()

    # Check that the checkout contains the expected files from sub-sub-project
    assert os.path.exists(os.path.join(checkoutdir, "hello.txt"))


#
# Test links to elements, this tests both specifying the link as
# the main target, and also as a dependency of the main target, while
# also using a conditional statement in the link
#
@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.parametrize("target", ["target.bst", "target-link.bst"])
@pytest.mark.parametrize("greeting,expected_file", [("hello", "hello.txt"), ("goodbye", "goodbye.txt")])
def test_conditional_link(cli, tmpdir, datafiles, target, greeting, expected_file):
    project = os.path.join(str(datafiles), "conditional")
    checkoutdir = os.path.join(str(tmpdir), "checkout")

    # Build, checkout
    result = cli.run(project=project, args=["-o", "greeting", greeting, "build", target])
    result.assert_success()
    result = cli.run(
        project=project, args=["-o", "greeting", greeting, "artifact", "checkout", target, "--directory", checkoutdir]
    )
    result.assert_success()

    # Check that the checkout contains the expected files from sub-sub-project
    assert os.path.exists(os.path.join(checkoutdir, expected_file))


#
# Test links to junctions from local projects and subprojects
#
@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.parametrize(
    "target", ["target-local.bst", "target-nested.bst", "full-path-link.bst", "target-full-path.bst"]
)
def test_simple_junctions(cli, tmpdir, datafiles, target):
    project = os.path.join(str(datafiles), "simple-junctions")
    checkoutdir = os.path.join(str(tmpdir), "checkout")

    # Build, checkout
    result = cli.run(project=project, args=["build", target])
    result.assert_success()
    result = cli.run(project=project, args=["artifact", "checkout", target, "--directory", checkoutdir])
    result.assert_success()

    # Check that the checkout contains the expected files from sub-sub-project
    assert os.path.exists(os.path.join(checkoutdir, "hello.txt"))


#
# Test links which resolve junction targets conditionally
#
@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.parametrize("greeting,expected_file", [("hello", "hello.txt"), ("goodbye", "goodbye.txt")])
def test_conditional_junctions(cli, tmpdir, datafiles, greeting, expected_file):
    project = os.path.join(str(datafiles), "conditional-junctions")
    checkoutdir = os.path.join(str(tmpdir), "checkout")

    # Build, checkout
    result = cli.run(project=project, args=["-o", "greeting", greeting, "build", "target.bst"])
    result.assert_success()
    result = cli.run(
        project=project,
        args=["-o", "greeting", greeting, "artifact", "checkout", "target.bst", "--directory", checkoutdir],
    )
    result.assert_success()

    # Check that the checkout contains the expected files from sub-sub-project
    assert os.path.exists(os.path.join(checkoutdir, expected_file))


#
# Tests links which refer to non-existing elements or junctions
#
@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.parametrize(
    "target,provenance",
    [
        # Target is a link to a non-existing local element
        ("link-target.bst", "link-target.bst [line 4 column 10]"),
        # Target is a stack depending on a link to a non-existing local element
        ("depends-on-link-target.bst", "link-target.bst [line 4 column 10]",),
        # Depends on non-existing subproject element, via a local link
        ("linked-local-junction-target.bst", "linked-local-junction-target.bst [line 4 column 2]",),
        # Depends on non-existing subsubproject element, via a local link
        ("linked-nested-junction-target.bst", "linked-nested-junction-target.bst [line 4 column 2]",),
        # Depends on an element via a link to a non-existing local junction
        ("linked-local-junction.bst", "subproject-link-notfound.bst [line 4 column 10]",),
        # Depends on an element via a link to a non-existing subproject junction
        ("linked-nested-junction.bst", "subsubproject-link-notfound.bst [line 4 column 10]",),
        # Target is a link to a non-existing nested element referred to with a full path
        ("link-full-path.bst", "link-full-path.bst [line 4 column 10]"),
        # Target depends on a link to a non-existing nested element referred to with a full path
        ("target-full-path.bst", "link-full-path.bst [line 4 column 10]"),
    ],
)
def test_link_not_found(cli, tmpdir, datafiles, target, provenance):
    project = os.path.join(str(datafiles), "notfound")
    result = cli.run(project=project, args=["build", target])

    result.assert_main_error(ErrorDomain.LOAD, LoadErrorReason.MISSING_FILE)
    assert provenance in result.stderr


#
# Tests links with invalid configurations
#
@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.parametrize(
    "target,expected_error,expected_reason",
    [
        # Test link which declares sources, either directly of via a dependency
        ("link-with-sources.bst", ErrorDomain.ELEMENT, "element-forbidden-sources"),
        ("target-link-with-sources.bst", ErrorDomain.ELEMENT, "element-forbidden-sources"),
        # Test link which declares dependencies, either directly of via a dependency
        ("link-with-dependencies.bst", ErrorDomain.LOAD, LoadErrorReason.LINK_FORBIDDEN_DEPENDENCIES),
    ],
)
def test_link_invalid_config(cli, tmpdir, datafiles, target, expected_error, expected_reason):
    project = os.path.join(str(datafiles), "invalid")
    result = cli.run(project=project, args=["show", target])
    result.assert_main_error(expected_error, expected_reason)


#
# Test including files across the boundry a link to a subproject's junction
#
@pytest.mark.datafiles(DATA_DIR)
def test_cross_link_junction_include(cli, tmpdir, datafiles):
    project = os.path.join(str(datafiles), "cross-link-junction-include")

    # Show the variables and parse our test variable from the subsubproject
    result = cli.run(project=project, args=["show", "--format", "%{vars}", "target.bst"])
    result.assert_success()

    # Read back some of our project defaults from the env
    variables = _yaml.load_data(result.output)
    assert variables.get_str("test") == "the test"
