# 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 loaded.get_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.roundtrip_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.roundtrip_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 loaded.get_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 loaded.get_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.roundtrip_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 loaded.get_str('included', default=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.roundtrip_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 loaded.get_str('included', default=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 loaded.get_str('manual_main_override', default=None) is not None
    assert loaded.get_str('manual_included_override', default=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 loaded.get_str_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 = loaded.get_mapping('bst')
    assert 'foo-commands' in bst
    assert bst.get_str_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 loaded.get_str('included', default=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 loaded.get_str('main_override', default=None) is not None
    assert loaded.get_str('included_override', default=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 loaded.get_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 loaded.get_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 loaded.get_bool('included')
