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

import os
import sys

import pytest

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


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

# List of BuildStream protected variables
PROTECTED_VARIABLES = [("project-name"), ("element-name"), ("max-jobs")]


def print_warning(msg):
    RED, END = "\033[91m", "\033[0m"
    print(("\n{}{}{}").format(RED, msg, END), file=sys.stderr)


###############################################################
#  Test proper loading of some default commands from plugins  #
###############################################################
@pytest.mark.parametrize(
    "target,varname,expected", [("autotools.bst", "make-install", 'make -j1 DESTDIR="/buildstream-install" install')],
)
@pytest.mark.datafiles(os.path.join(DATA_DIR, "defaults"))
def test_defaults(cli, datafiles, target, varname, expected):
    project = str(datafiles)
    result = cli.run(project=project, silent=True, args=["show", "--deps", "none", "--format", "%{vars}", target])
    result.assert_success()
    result_vars = _yaml.load_data(result.output)
    assert result_vars.get_str(varname) == expected


################################################################
#  Test overriding of variables to produce different commands  #
################################################################
@pytest.mark.parametrize(
    "target,varname,expected", [("autotools.bst", "make-install", 'make -j1 DESTDIR="/custom/install/root" install')],
)
@pytest.mark.datafiles(os.path.join(DATA_DIR, "overrides"))
def test_overrides(cli, datafiles, target, varname, expected):
    project = str(datafiles)
    result = cli.run(project=project, silent=True, args=["show", "--deps", "none", "--format", "%{vars}", target])
    result.assert_success()
    result_vars = _yaml.load_data(result.output)
    assert result_vars.get_str(varname) == expected


@pytest.mark.parametrize(
    "element,provenance",
    [
        # This test makes a reference to an undefined variable in a build command
        ("manual.bst", "manual.bst [line 5 column 6]"),
        # This test makes a reference to an undefined variable by another variable,
        # ensuring that we validate variables even when they are unused
        ("manual2.bst", "manual2.bst [line 4 column 8]"),
        # This test uses a build command to refer to some variables which ultimately
        # refer to an undefined variable, testing a more complex case.
        ("manual3.bst", "manual3.bst [line 6 column 8]"),
    ],
    ids=["build-command", "variables", "complex"],
)
@pytest.mark.datafiles(os.path.join(DATA_DIR, "missing_variables"))
def test_undefined(cli, datafiles, element, provenance):
    project = str(datafiles)
    result = cli.run(project=project, silent=True, args=["show", "--deps", "none", "--format", "%{config}", element])
    result.assert_main_error(ErrorDomain.LOAD, LoadErrorReason.UNRESOLVED_VARIABLE)
    assert provenance in result.stderr


@pytest.mark.parametrize(
    "element,provenances",
    [
        # Test a simple a -> b and b -> a reference
        ("simple-cyclic.bst", ["simple-cyclic.bst [line 4 column 5]", "simple-cyclic.bst [line 5 column 5]"]),
        # Test a simple a -> b and b -> a reference with some text involved
        ("cyclic.bst", ["cyclic.bst [line 5 column 10]", "cyclic.bst [line 4 column 5]"]),
        # Test an indirect circular dependency
        (
            "indirect-cyclic.bst",
            [
                "indirect-cyclic.bst [line 5 column 5]",
                "indirect-cyclic.bst [line 6 column 5]",
                "indirect-cyclic.bst [line 7 column 5]",
                "indirect-cyclic.bst [line 8 column 5]",
            ],
        ),
        # Test an indirect circular dependency
        ("self-reference.bst", ["self-reference.bst [line 4 column 5]"]),
    ],
    ids=["simple", "simple-text", "indirect", "self-reference"],
)
@pytest.mark.timeout(30, method="signal")
@pytest.mark.datafiles(os.path.join(DATA_DIR, "cyclic_variables"))
def test_circular_reference(cli, datafiles, element, provenances):
    print_warning("Performing cyclic test, if this test times out it will exit the test sequence")
    project = str(datafiles)
    result = cli.run(project=project, silent=True, args=["build", element])
    result.assert_main_error(ErrorDomain.LOAD, LoadErrorReason.CIRCULAR_REFERENCE_VARIABLE)
    for provenance in provenances:
        assert provenance in result.stderr


# Test that variables which refer to eachother very deeply are
# still resolved correctly, this ensures that we are not relying
# on a recursive algorithm limited by stack depth.
#
@pytest.mark.parametrize(
    "maxvars", [50, 500, 5000],
)
@pytest.mark.datafiles(os.path.join(DATA_DIR, "defaults"))
def test_deep_references(cli, datafiles, maxvars):
    project = str(datafiles)

    # Generate an element with very, very many variables to resolve,
    # each which expand to the value of the previous variable.
    #
    # The bottom variable defines a test value which we check for
    # in the top variable in `bst show` output.
    #
    topvar = "var{}".format(maxvars)
    bottomvar = "var0"
    testvalue = "testvalue {}".format(maxvars)

    # Generate
    variables = {"var{}".format(idx + 1): "%{var" + str(idx) + "}" for idx in range(maxvars)}
    variables[bottomvar] = testvalue
    element = {"kind": "manual", "variables": variables}
    _yaml.roundtrip_dump(element, os.path.join(project, "test.bst"))

    # Run `bst show`
    result = cli.run(project=project, args=["show", "--format", "%{vars}", "test.bst"])
    result.assert_success()

    # Test results
    result_vars = _yaml.load_data(result.output)
    assert result_vars.get_str(topvar) == testvalue


@pytest.mark.parametrize("protected_var", PROTECTED_VARIABLES)
@pytest.mark.datafiles(os.path.join(DATA_DIR, "protected-vars"))
def test_use_of_protected_var_project_conf(cli, datafiles, protected_var):
    project = str(datafiles)
    conf = {"name": "test", "min-version": "2.0", "variables": {protected_var: "some-value"}}
    _yaml.roundtrip_dump(conf, os.path.join(project, "project.conf"))

    element = {
        "kind": "import",
        "sources": [{"kind": "local", "path": "foo.txt"}],
    }
    _yaml.roundtrip_dump(element, os.path.join(project, "target.bst"))

    result = cli.run(project=project, args=["build", "target.bst"])
    result.assert_main_error(ErrorDomain.LOAD, LoadErrorReason.PROTECTED_VARIABLE_REDEFINED)


@pytest.mark.parametrize("protected_var", PROTECTED_VARIABLES)
@pytest.mark.datafiles(os.path.join(DATA_DIR, "protected-vars"))
def test_use_of_protected_var_element_overrides(cli, datafiles, protected_var):
    project = str(datafiles)
    conf = {"name": "test", "min-version": "2.0", "elements": {"manual": {"variables": {protected_var: "some-value"}}}}
    _yaml.roundtrip_dump(conf, os.path.join(project, "project.conf"))

    element = {
        "kind": "manual",
        "sources": [{"kind": "local", "path": "foo.txt"}],
    }
    _yaml.roundtrip_dump(element, os.path.join(project, "target.bst"))

    result = cli.run(project=project, args=["build", "target.bst"])
    result.assert_main_error(ErrorDomain.LOAD, LoadErrorReason.PROTECTED_VARIABLE_REDEFINED)


@pytest.mark.parametrize("protected_var", PROTECTED_VARIABLES)
@pytest.mark.datafiles(os.path.join(DATA_DIR, "protected-vars"))
def test_use_of_protected_var_in_element(cli, datafiles, protected_var):
    project = str(datafiles)
    element = {
        "kind": "import",
        "sources": [{"kind": "local", "path": "foo.txt"}],
        "variables": {protected_var: "some-value"},
    }
    _yaml.roundtrip_dump(element, os.path.join(project, "target.bst"))

    result = cli.run(project=project, args=["build", "target.bst"])
    result.assert_main_error(ErrorDomain.LOAD, LoadErrorReason.PROTECTED_VARIABLE_REDEFINED)


@pytest.mark.datafiles(os.path.join(DATA_DIR, "shared_variables"))
def test_variables_are_resolved_in_elements_context(cli, datafiles):
    project = str(datafiles)

    result = cli.run(project=project, args=["build"])
    result.assert_success()

    checkout_dir = os.path.join(project, "checkout")
    for elem in ["one", "two"]:
        result = cli.run(
            project=project,
            args=["artifact", "checkout", "--directory", os.path.join(checkout_dir, elem), "{}.bst".format(elem)],
        )
        result.assert_success()

    assert (os.listdir(os.path.join(checkout_dir, "one")), os.listdir(os.path.join(checkout_dir, "two"))) == (
        ["one.bst"],
        ["two.bst"],
    )


@pytest.mark.datafiles(os.path.join(DATA_DIR, "public_data_variables"))
def test_variables_are_resolved_in_public_section(cli, datafiles):
    project = str(datafiles)

    result = cli.run(project=project, args=["show", "--format", "%{public}", "public.bst"])
    result.assert_success()

    output = _yaml.load_data(result.output).strip_node_info()
    expected = {"integration-commands": ["echo expanded"], "test": "expanded"}

    assert {k: v for k, v in output.items() if k in expected} == expected


@pytest.mark.datafiles(os.path.join(DATA_DIR, "public_data_variables"))
def test_variables_resolving_errors_in_public_section(cli, datafiles):
    project = str(datafiles)

    result = cli.run(project=project, args=["show", "--format", "%{public}", "public_unresolved.bst"])
    result.assert_main_error(ErrorDomain.LOAD, LoadErrorReason.UNRESOLVED_VARIABLE)


@pytest.mark.datafiles(os.path.join(DATA_DIR, "partial_context"))
def test_partial_context_junctions(cli, datafiles):
    project = str(datafiles)

    result = cli.run(project=project, args=["show", "--format", "%{vars}", "test.bst"])
    result.assert_success()
    result_vars = _yaml.load_data(result.output)
    assert result_vars.get_str("eltvar") == "/bar/foo/baz"


# The notparallel tests use a custom plugin which recreates a situation where
# a plugin substitutes an environment variable with the protected %{max-jobs}
# variable, which is set depending on whether the plugin declared notparallel.
#
# These are a regression test against issue #1360, where we found variable
# substitution at the plugin default YAML was buggy when multiple instances
# were not getting the correct results.
#
@pytest.mark.datafiles(os.path.join(DATA_DIR, "notparallel"))
def test_notparallel(cli, datafiles):
    project = str(datafiles)

    # Test the vars
    result = cli.run(project=project, args=["show", "--format", "%{vars}%{env}", "notparallel.bst"])
    result.assert_success()
    result_vars = _yaml.load_data(result.output)
    assert result_vars.get_str("element-name") == "notparallel.bst"
    assert result_vars.get_str("max-jobs") == "1"
    assert result_vars.get_str("MAKEFLAGS") == "-j1"


@pytest.mark.datafiles(os.path.join(DATA_DIR, "notparallel"))
def test_notparallel_twice(cli, datafiles):
    project = str(datafiles)

    #
    # Explicitly configure default max-jobs using user configuration
    #
    cli.configure({"build": {"max-jobs": 2}})

    # Fetch the variables and environment of both elements, where parallel.bst depends on notparallel.bst
    result = cli.run(project=project, args=["show", "--format", "%{vars}%{env}", "parallel.bst"])
    result.assert_success()

    # Split on the empty line, which separates elements in bst show output
    groups = result.output.split("\n\n")
    assert len(groups) >= 2
    notparallel_vars = _yaml.load_data(groups[0])
    parallel_vars = _yaml.load_data(groups[1])

    # Test the first group for the expected notparallel state
    assert notparallel_vars.get_str("element-name") == "notparallel.bst"
    assert notparallel_vars.get_str("max-jobs") == "1"
    assert notparallel_vars.get_str("MAKEFLAGS") == "-j1"

    # Test the second group for the expected !notparallel state
    assert parallel_vars.get_str("element-name") == "parallel.bst"
    assert parallel_vars.get_str("max-jobs") == "2"
    assert parallel_vars.get_str("MAKEFLAGS") == "-j2"
