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

import os
import textwrap
import pytest
from buildstream import _yaml
from buildstream._exceptions import ErrorDomain, LoadErrorReason
from buildstream.testing import cli  # pylint: disable=unused-import
from buildstream.testing import create_repo
from tests.testutils import generate_junction


# Project directory
DATA_DIR = os.path.join(
    os.path.dirname(os.path.realpath(__file__)),
    'include'
)


@pytest.mark.datafiles(DATA_DIR)
def test_include_project_file(cli, datafiles):
    project = os.path.join(str(datafiles), 'file')
    result = cli.run(project=project, args=[
        'show',
        '--deps', 'none',
        '--format', '%{vars}',
        'element.bst'])
    result.assert_success()
    loaded = _yaml.load_data(result.output)
    assert _yaml.node_get(loaded, bool, 'included')


def test_include_missing_file(cli, tmpdir):
    tmpdir.join('project.conf').write('{"name": "test"}')
    element = tmpdir.join('include_missing_file.bst')

    # Normally we would use dicts and _yaml.dump to write such things, but here
    # we want to be sure of a stable line and column number.
    element.write(textwrap.dedent("""
        kind: manual

        "(@)":
          - nosuch.yaml
    """).strip())

    result = cli.run(project=str(tmpdir), args=['show', str(element.basename)])
    result.assert_main_error(ErrorDomain.LOAD, LoadErrorReason.MISSING_FILE)
    # Make sure the root cause provenance is in the output.
    assert 'line 4 column 2' in result.stderr


def test_include_dir(cli, tmpdir):
    tmpdir.join('project.conf').write('{"name": "test"}')
    tmpdir.mkdir('subdir')
    element = tmpdir.join('include_dir.bst')

    # Normally we would use dicts and _yaml.dump to write such things, but here
    # we want to be sure of a stable line and column number.
    element.write(textwrap.dedent("""
        kind: manual

        "(@)":
          - subdir/
    """).strip())

    result = cli.run(project=str(tmpdir), args=['show', str(element.basename)])
    result.assert_main_error(
        ErrorDomain.LOAD, LoadErrorReason.LOADING_DIRECTORY)
    # Make sure the root cause provenance is in the output.
    assert 'line 4 column 2' in result.stderr


@pytest.mark.datafiles(DATA_DIR)
def test_include_junction_file(cli, tmpdir, datafiles):
    project = os.path.join(str(datafiles), 'junction')

    generate_junction(tmpdir,
                      os.path.join(project, 'subproject'),
                      os.path.join(project, 'junction.bst'),
                      store_ref=True)

    result = cli.run(project=project, args=[
        'show',
        '--deps', 'none',
        '--format', '%{vars}',
        'element.bst'])
    result.assert_success()
    loaded = _yaml.load_data(result.output)
    assert _yaml.node_get(loaded, bool, 'included')


@pytest.mark.datafiles(DATA_DIR)
def test_include_junction_options(cli, datafiles):
    project = os.path.join(str(datafiles), 'options')

    result = cli.run(project=project, args=[
        '-o', 'build_arch', 'x86_64',
        'show',
        '--deps', 'none',
        '--format', '%{vars}',
        'element.bst'])
    result.assert_success()
    loaded = _yaml.load_data(result.output)
    assert _yaml.node_get(loaded, str, 'build_arch') == 'x86_64'


@pytest.mark.datafiles(DATA_DIR)
def test_junction_element_partial_project_project(cli, tmpdir, datafiles):
    """
    Junction elements never depend on fully include processed project.
    """

    project = os.path.join(str(datafiles), 'junction')

    subproject_path = os.path.join(project, 'subproject')
    junction_path = os.path.join(project, 'junction.bst')

    repo = create_repo('git', str(tmpdir))

    ref = repo.create(subproject_path)

    element = {
        'kind': 'junction',
        'sources': [
            repo.source_config(ref=ref)
        ]
    }
    _yaml.dump(element, junction_path)

    result = cli.run(project=project, args=[
        'show',
        '--deps', 'none',
        '--format', '%{vars}',
        'junction.bst'])
    result.assert_success()
    loaded = _yaml.load_data(result.output)
    assert _yaml.node_get(loaded, str, 'included', default_value=None) is None


@pytest.mark.datafiles(DATA_DIR)
def test_junction_element_not_partial_project_file(cli, tmpdir, datafiles):
    """
    Junction elements never depend on fully include processed project.
    """

    project = os.path.join(str(datafiles), 'file_with_subproject')

    subproject_path = os.path.join(project, 'subproject')
    junction_path = os.path.join(project, 'junction.bst')

    repo = create_repo('git', str(tmpdir))

    ref = repo.create(subproject_path)

    element = {
        'kind': 'junction',
        'sources': [
            repo.source_config(ref=ref)
        ]
    }
    _yaml.dump(element, junction_path)

    result = cli.run(project=project, args=[
        'show',
        '--deps', 'none',
        '--format', '%{vars}',
        'junction.bst'])
    result.assert_success()
    loaded = _yaml.load_data(result.output)
    assert _yaml.node_get(loaded, str, 'included', default_value=None) is not None


@pytest.mark.datafiles(DATA_DIR)
def test_include_element_overrides(cli, datafiles):
    project = os.path.join(str(datafiles), 'overrides')

    result = cli.run(project=project, args=[
        'show',
        '--deps', 'none',
        '--format', '%{vars}',
        'element.bst'])
    result.assert_success()
    loaded = _yaml.load_data(result.output)
    assert _yaml.node_get(loaded, str, 'manual_main_override', default_value=None) is not None
    assert _yaml.node_get(loaded, str, 'manual_included_override', default_value=None) is not None


@pytest.mark.datafiles(DATA_DIR)
def test_include_element_overrides_composition(cli, datafiles):
    project = os.path.join(str(datafiles), 'overrides')

    result = cli.run(project=project, args=[
        'show',
        '--deps', 'none',
        '--format', '%{config}',
        'element.bst'])
    result.assert_success()
    loaded = _yaml.load_data(result.output)
    assert _yaml.node_get(loaded, list, 'build-commands') == ['first', 'second']


@pytest.mark.datafiles(DATA_DIR)
def test_list_overide_does_not_fail_upon_first_composition(cli, datafiles):
    project = os.path.join(str(datafiles), 'eventual_overrides')

    result = cli.run(project=project, args=[
        'show',
        '--deps', 'none',
        '--format', '%{public}',
        'element.bst'])
    result.assert_success()
    loaded = _yaml.load_data(result.output)

    # Assert that the explicitly overwritten public data is present
    bst = _yaml.node_get(loaded, dict, 'bst')
    assert 'foo-commands' in bst
    assert _yaml.node_get(bst, list, 'foo-commands') == ['need', 'this']


@pytest.mark.datafiles(DATA_DIR)
def test_include_element_overrides_sub_include(cli, datafiles):
    project = os.path.join(str(datafiles), 'sub-include')

    result = cli.run(project=project, args=[
        'show',
        '--deps', 'none',
        '--format', '%{vars}',
        'element.bst'])
    result.assert_success()
    loaded = _yaml.load_data(result.output)
    assert _yaml.node_get(loaded, str, 'included', default_value=None) is not None


@pytest.mark.datafiles(DATA_DIR)
def test_junction_do_not_use_included_overrides(cli, tmpdir, datafiles):
    project = os.path.join(str(datafiles), 'overrides-junction')

    generate_junction(tmpdir,
                      os.path.join(project, 'subproject'),
                      os.path.join(project, 'junction.bst'),
                      store_ref=True)

    result = cli.run(project=project, args=[
        'show',
        '--deps', 'none',
        '--format', '%{vars}',
        'junction.bst'])
    result.assert_success()
    loaded = _yaml.load_data(result.output)
    assert _yaml.node_get(loaded, str, 'main_override', default_value=None) is not None
    assert _yaml.node_get(loaded, str, 'included_override', default_value=None) is None


@pytest.mark.datafiles(DATA_DIR)
def test_conditional_in_fragment(cli, datafiles):
    project = os.path.join(str(datafiles), 'conditional')

    result = cli.run(project=project, args=[
        '-o', 'build_arch', 'x86_64',
        'show',
        '--deps', 'none',
        '--format', '%{vars}',
        'element.bst'])
    result.assert_success()
    loaded = _yaml.load_data(result.output)
    assert _yaml.node_get(loaded, str, 'size') == '8'


@pytest.mark.datafiles(DATA_DIR)
def test_inner(cli, datafiles):
    project = os.path.join(str(datafiles), 'inner')
    result = cli.run(project=project, args=[
        '-o', 'build_arch', 'x86_64',
        'show',
        '--deps', 'none',
        '--format', '%{vars}',
        'element.bst'])
    result.assert_success()
    loaded = _yaml.load_data(result.output)
    assert _yaml.node_get(loaded, str, 'build_arch') == 'x86_64'


@pytest.mark.datafiles(DATA_DIR)
def test_recursive_include(cli, datafiles):
    project = os.path.join(str(datafiles), 'recursive')

    result = cli.run(project=project, args=[
        'show',
        '--deps', 'none',
        '--format', '%{vars}',
        'element.bst'])
    result.assert_main_error(ErrorDomain.LOAD, LoadErrorReason.RECURSIVE_INCLUDE)
    assert 'line 2 column 2' in result.stderr


@pytest.mark.datafiles(DATA_DIR)
def test_local_to_junction(cli, tmpdir, datafiles):
    project = os.path.join(str(datafiles), 'local_to_junction')

    generate_junction(tmpdir,
                      os.path.join(project, 'subproject'),
                      os.path.join(project, 'junction.bst'),
                      store_ref=True)

    result = cli.run(project=project, args=[
        'show',
        '--deps', 'none',
        '--format', '%{vars}',
        'element.bst'])
    result.assert_success()
    loaded = _yaml.load_data(result.output)
    assert _yaml.node_get(loaded, bool, 'included')
