import os
import pytest
from tests.testutils import cli, create_repo, ALL_REPO_KINDS
from buildstream import _yaml

from . import generate_junction


def generate_element(repo, element_path, dep_name=None):
    element = {
        'kind': 'import',
        'sources': [
            repo.source_config()
        ]
    }
    if dep_name:
        element['depends'] = [dep_name]

    _yaml.dump(element, element_path)


def generate_import_element(tmpdir, kind, project, name):
    element_name = 'import-{}.bst'.format(name)
    repo_element_path = os.path.join(project, 'elements', element_name)
    files = str(tmpdir.join("imported_files_{}".format(name)))
    os.makedirs(files)

    with open(os.path.join(files, '{}.txt'.format(name)), 'w') as f:
        f.write(name)

    subproject_path = os.path.join(str(tmpdir.join('sub-project-{}'.format(name))))

    repo = create_repo(kind, str(tmpdir.join('element_{}_repo'.format(name))))
    ref = repo.create(files)

    generate_element(repo, repo_element_path)

    return element_name


def generate_project(tmpdir, name, config={}):
    project_name = 'project-{}'.format(name)
    subproject_path = os.path.join(str(tmpdir.join(project_name)))
    os.makedirs(os.path.join(subproject_path, 'elements'))

    project_conf = {
        'name': name,
        'element-path': 'elements'
    }
    project_conf.update(config)
    _yaml.dump(project_conf, os.path.join(subproject_path, 'project.conf'))

    return project_name, subproject_path


def generate_simple_stack(project, name, dependencies):
    element_name = '{}.bst'.format(name)
    element_path = os.path.join(project, 'elements', element_name)
    element = {
        'kind': 'stack',
        'depends': dependencies
    }
    _yaml.dump(element, element_path)

    return element_name


def generate_cross_element(project, subproject_name, import_name):
    basename, _ = os.path.splitext(import_name)
    return generate_simple_stack(project, 'import-{}-{}'.format(subproject_name, basename),
                                 [{
                                     'junction': '{}.bst'.format(subproject_name),
                                     'filename': import_name
                                 }])


@pytest.mark.parametrize("kind", [(kind) for kind in ALL_REPO_KINDS])
def test_cross_junction_multiple_projects(cli, tmpdir, datafiles, kind):
    tmpdir = tmpdir.join(kind)

    # Generate 3 projects: main, a, b
    _, project = generate_project(tmpdir, 'main', {'ref-storage': 'project.refs'})
    project_a, project_a_path = generate_project(tmpdir, 'a')
    project_b, project_b_path = generate_project(tmpdir, 'b')

    # Generate an element with a trackable source for each project
    element_a = generate_import_element(tmpdir, kind, project_a_path, 'a')
    element_b = generate_import_element(tmpdir, kind, project_b_path, 'b')
    element_c = generate_import_element(tmpdir, kind, project, 'c')

    # Create some indirections to the elements with dependencies to test --deps
    stack_a = generate_simple_stack(project_a_path, 'stack-a', [element_a])
    stack_b = generate_simple_stack(project_b_path, 'stack-b', [element_b])

    # Create junctions for projects a and b in main.
    junction_a = '{}.bst'.format(project_a)
    junction_a_path = os.path.join(project, 'elements', junction_a)
    generate_junction(tmpdir.join('repo_a'), project_a_path, junction_a_path, store_ref=False)

    junction_b = '{}.bst'.format(project_b)
    junction_b_path = os.path.join(project, 'elements', junction_b)
    generate_junction(tmpdir.join('repo_b'), project_b_path, junction_b_path, store_ref=False)

    # Track the junctions.
    result = cli.run(project=project, args=['track', junction_a, junction_b])
    result.assert_success()

    # Import elements from a and b in to main.
    imported_a = generate_cross_element(project, project_a, stack_a)
    imported_b = generate_cross_element(project, project_b, stack_b)

    # Generate a top level stack depending on everything
    all_bst = generate_simple_stack(project, 'all', [imported_a, imported_b, element_c])

    # Track without following junctions. But explicitly also track the elements in project a.
    result = cli.run(project=project, args=['track', '--deps', 'all', all_bst, '{}:{}'.format(junction_a, stack_a)])
    result.assert_success()

    # Elements in project b should not be tracked. But elements in project a and main should.
    expected = [element_c,
                '{}:{}'.format(junction_a, element_a)]
    assert set(result.get_tracked_elements()) == set(expected)


@pytest.mark.parametrize("kind", [(kind) for kind in ALL_REPO_KINDS])
def test_track_exceptions(cli, tmpdir, datafiles, kind):
    tmpdir = tmpdir.join(kind)

    _, project = generate_project(tmpdir, 'main', {'ref-storage': 'project.refs'})
    project_a, project_a_path = generate_project(tmpdir, 'a')

    element_a = generate_import_element(tmpdir, kind, project_a_path, 'a')
    element_b = generate_import_element(tmpdir, kind, project_a_path, 'b')

    all_bst = generate_simple_stack(project_a_path, 'all', [element_a,
                                                            element_b])

    junction_a = '{}.bst'.format(project_a)
    junction_a_path = os.path.join(project, 'elements', junction_a)
    generate_junction(tmpdir.join('repo_a'), project_a_path, junction_a_path, store_ref=False)

    result = cli.run(project=project, args=['track', junction_a])
    result.assert_success()

    imported_b = generate_cross_element(project, project_a, element_b)
    indirection = generate_simple_stack(project, 'indirection', [imported_b])

    result = cli.run(project=project,
                     args=['track', '--deps', 'all',
                           '--except', indirection,
                           '{}:{}'.format(junction_a, all_bst), imported_b])
    result.assert_success()

    expected = ['{}:{}'.format(junction_a, element_a),
                '{}:{}'.format(junction_a, element_b)]
    assert set(result.get_tracked_elements()) == set(expected)
