# 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.exceptions import ErrorDomain, LoadErrorReason
from buildstream._testing.runcli import cli  # pylint: disable=unused-import

# Project directory
DATA_DIR = os.path.dirname(os.path.realpath(__file__))


@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.parametrize(
    "target,option,value,expected",
    [
        # Test (var == [ "foo" ]) syntax
        ("element.bst", "farm", "pony", "a pony"),
        ("element.bst", "farm", "zebry", "a zebry"),
        ("element.bst", "farm", "pony, horsy", "a pony and a horsy"),
        ("element.bst", "farm", "zebry,horsy , pony", "all the animals"),
        # Test ("literal" in var) syntax
        ("element-in.bst", "farm", "zebry, horsy, pony", "a zebry"),
        # Test ("literal" not in var) syntax
        ("element-in.bst", "farm", "zebry, horsy", "no pony"),
        # Test (var1 not in var2) syntax (where var1 is enum and var2 is flags)
        ("element-in.bst", "farm", "zebry, pony", "no horsy"),
    ],
)
def test_conditional_cli(cli, datafiles, target, option, value, expected):
    project = os.path.join(datafiles.dirname, datafiles.basename, "option-flags")
    result = cli.run(
        project=project,
        silent=True,
        args=["--option", option, value, "show", "--deps", "none", "--format", "%{vars}", target],
    )

    result.assert_success()
    loaded = _yaml.load_data(result.output)
    assert loaded.get_str("result") == expected


@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.parametrize(
    "target,option,value,expected",
    [
        # Test 'var == [ "foo" ]' syntax
        ("element.bst", "farm", ["pony"], "a pony"),
        ("element.bst", "farm", ["zebry"], "a zebry"),
        ("element.bst", "farm", ["pony", "horsy"], "a pony and a horsy"),
        ("element.bst", "farm", ["zebry", "horsy", "pony"], "all the animals"),
    ],
)
def test_conditional_config(cli, datafiles, target, option, value, expected):
    project = os.path.join(datafiles.dirname, datafiles.basename, "option-flags")
    cli.configure({"projects": {"test": {"options": {option: value}}}})
    result = cli.run(project=project, silent=True, args=["show", "--deps", "none", "--format", "%{vars}", target])

    result.assert_success()
    loaded = _yaml.load_data(result.output)
    assert loaded.get_str("result") == expected


@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.parametrize(
    "cli_option",
    [("giraffy"), ("horsy pony")],  # Not a valid animal for the farm option  # Does not include comma separators
)
def test_invalid_value_cli(cli, datafiles, cli_option):
    project = os.path.join(datafiles.dirname, datafiles.basename, "option-flags")
    result = cli.run(
        project=project,
        silent=True,
        args=["--option", "farm", cli_option, "show", "--deps", "none", "--format", "%{vars}", "element.bst"],
    )
    result.assert_main_error(ErrorDomain.LOAD, LoadErrorReason.INVALID_DATA)


@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.parametrize(
    "config_option",
    [
        ("pony"),  # Not specified as a list
        (["horsy", "pony", "giraffy"]),  # Invalid giraffy animal for farm option
        ({"dic": "tionary"}),  # Dicts also dont make sense in the config for flags
    ],
)
def test_invalid_value_config(cli, datafiles, config_option):
    project = os.path.join(datafiles.dirname, datafiles.basename, "option-flags")
    cli.configure({"projects": {"test": {"options": {"farm": config_option}}}})
    result = cli.run(
        project=project, silent=True, args=["show", "--deps", "none", "--format", "%{vars}", "element.bst"]
    )
    result.assert_main_error(ErrorDomain.LOAD, LoadErrorReason.INVALID_DATA)


@pytest.mark.datafiles(DATA_DIR)
def test_missing_values(cli, datafiles):
    project = os.path.join(datafiles.dirname, datafiles.basename, "option-flags-missing")
    result = cli.run(
        project=project, silent=True, args=["show", "--deps", "none", "--format", "%{vars}", "element.bst"]
    )
    result.assert_main_error(ErrorDomain.LOAD, LoadErrorReason.INVALID_DATA)
