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

import os

import pytest
from buildstream._testing import create_repo
from buildstream._testing import cli  # pylint: disable=unused-import
from buildstream import _yaml

# Project directory
DATA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "project",)


# create_element()
#
# Args:
#    project (str): The project directory where testing is happening
#    name (str): The element name to create
#    dependencies (list): The list of dependencies to dump into YAML format
#
# Returns:
#    (Repo): The corresponding git repository created for the element
def create_element(project, name, dependencies):
    dev_files_path = os.path.join(project, "files", "dev-files")
    element_path = os.path.join(project, "elements")
    repo = create_repo("git", project, "{}-repo".format(name))
    ref = repo.create(dev_files_path)

    element = {"kind": "import", "sources": [repo.source_config(ref=ref)], "depends": dependencies}
    _yaml.roundtrip_dump(element, os.path.join(element_path, name))

    return repo


# This tests a variety of scenarios and checks that the order in
# which things are processed remains stable.
#
# This is especially important in order to ensure that our
# depth sorting and optimization of which elements should be
# processed first is doing it's job right, and that we are
# promoting elements to the build queue as soon as possible
#
# Parameters:
#    targets (target elements): The targets to invoke bst with
#    template (dict): The project template dictionary, for create_element()
#    expected (list): A list of element names in the expected order
#
@pytest.mark.datafiles(os.path.join(DATA_DIR))
@pytest.mark.parametrize(
    "target,template,expected_stage_order,expected_build_order",
    [
        # First simple test
        (
            "3.bst",
            {"0.bst": ["1.bst"], "1.bst": [], "2.bst": ["0.bst"], "3.bst": ["0.bst", "1.bst", "2.bst"]},
            ["1.bst", "0.bst", "2.bst", "3.bst"],
            ["1.bst", "0.bst", "2.bst", "3.bst"],
        ),
        # A more complicated test with build of build dependencies
        (
            "target.bst",
            {
                "a.bst": [],
                "base.bst": [],
                "timezones.bst": [],
                "middleware.bst": [{"filename": "base.bst", "type": "build"}],
                "app.bst": [{"filename": "middleware.bst", "type": "build"}],
                "target.bst": ["a.bst", "base.bst", "middleware.bst", "app.bst", "timezones.bst"],
            },
            ["a.bst", "base.bst", "middleware.bst", "app.bst", "timezones.bst", "target.bst"],
            ["base.bst", "middleware.bst", "a.bst", "app.bst", "timezones.bst", "target.bst"],
        ),
    ],
    ids=["simple", "complex"],
)
@pytest.mark.parametrize("operation", [("show"), ("fetch"), ("build")])
def test_order(cli, datafiles, operation, target, template, expected_stage_order, expected_build_order):
    project = str(datafiles)

    # Configure to only allow one fetcher at a time, make it easy to
    # determine what is being planned in what order.
    cli.configure({"scheduler": {"fetchers": 1, "builders": 1}})

    # Build the project from the template, make import elements
    # all with the same repo
    #
    for element, dependencies in template.items():
        create_element(project, element, dependencies)

    # Run test and collect results
    if operation == "show":
        result = cli.run(args=["show", "--deps", "all", "--format", "%{name}", target], project=project, silent=True)
        result.assert_success()
        results = result.output.splitlines()
    else:
        if operation == "fetch":
            result = cli.run(args=["source", "fetch", "--deps", "all", target], project=project, silent=True)
        else:
            result = cli.run(args=["build", target], project=project, silent=True)
        result.assert_success()
        results = result.get_start_order(operation)

    # When running `bst build`, the elements are depth sorted for optimal processing
    if operation == "build":
        expected = expected_build_order
    else:
        # Otherwise, we get the usual deterministic staging order
        expected = expected_stage_order

    # Assert the order
    print("Expected order: {}".format(expected))
    print("Observed result order: {}".format(results))
    assert results == expected
