# 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,expected",
    [
        # Test 'foo' syntax, and valid values of 'True' / 'False'
        ("element.bst", "True", "a pony"),
        ("element.bst", "true", "a pony"),
        ("element.bst", "False", "not pony"),
        ("element.bst", "false", "not pony"),
        # Test 'not foo' syntax
        ("element-not.bst", "False", "not pony"),
        ("element-not.bst", "True", "a pony"),
        # Test 'foo == True' syntax
        ("element-equals.bst", "False", "not pony"),
        ("element-equals.bst", "True", "a pony"),
        # Test 'foo != True' syntax
        ("element-not-equals.bst", "False", "not pony"),
        ("element-not-equals.bst", "True", "a pony"),
    ],
)
def test_conditional_cli(cli, datafiles, target, option, expected):
    project = os.path.join(datafiles.dirname, datafiles.basename, "option-bool")
    result = cli.run(
        project=project,
        silent=True,
        args=["--option", "pony", option, "show", "--deps", "none", "--format", "%{vars}", target],
    )
    result.assert_success()

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


# Test configuration of boolean option in the config file
#
@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.parametrize(
    "target,option,expected", [("element.bst", True, "a pony"), ("element.bst", False, "not pony"),]
)
def test_conditional_config(cli, datafiles, target, option, expected):
    project = os.path.join(datafiles.dirname, datafiles.basename, "option-bool")
    cli.configure({"projects": {"test": {"options": {"pony": option}}}})
    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("thepony") == expected


@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.parametrize("cli_option", [("falsey"), ("pony"), ("trUE")])
def test_invalid_value_cli(cli, datafiles, cli_option):
    project = os.path.join(datafiles.dirname, datafiles.basename, "option-bool")
    result = cli.run(
        project=project,
        silent=True,
        args=["--option", "pony", 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"), (["its", "a", "list"]), ({"dic": "tionary"})])
def test_invalid_value_config(cli, datafiles, config_option):
    project = os.path.join(datafiles.dirname, datafiles.basename, "option-bool")
    cli.configure({"projects": {"test": {"options": {"pony": 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)
