import os
import pytest
from buildstream import _yaml
from buildstream import LoadError, LoadErrorReason
from tests.testutils.runcli import cli

# 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])

    assert result.exit_code == 0
    loaded = _yaml.load_data(result.output)
    assert loaded['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])

    assert result.exit_code == 0
    loaded = _yaml.load_data(result.output)
    assert loaded['result'] == expected


@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.parametrize("cli_option", [
    ('giraffy'),     # Not a valid animal for the farm option
    ('horsy pony')   # 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'])
    assert result.exit_code != 0
    assert result.exception
    assert isinstance(result.exception, LoadError)
    assert result.exception.reason == 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'])
    assert result.exit_code != 0
    assert result.exception
    assert isinstance(result.exception, LoadError)
    assert result.exception.reason == 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'])
    assert result.exit_code != 0
    assert result.exception
    assert isinstance(result.exception, LoadError)
    assert result.exception.reason == LoadErrorReason.INVALID_DATA
