# 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 cli  # pylint: disable=unused-import

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


def strict_args(args, strict):
    if strict != "strict":
        return ["--no-strict", *args]
    return args


@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.parametrize("strict", ["strict", "non-strict"])
def test_rebuild(datafiles, cli, strict):
    project = str(datafiles)

    # First build intermediate target.bst
    result = cli.run(project=project, args=strict_args(["build", "target.bst"], strict))
    result.assert_success()

    # Modify base import
    with open(os.path.join(project, "files", "dev-files", "usr", "include", "new.h"), "w") as f:
        f.write("#define NEW")

    # Rebuild base import and build top-level rebuild-target.bst
    # In non-strict mode, this does not rebuild intermediate target.bst,
    # which means that a weakly cached target.bst will be staged as dependency.
    result = cli.run(project=project, args=strict_args(["build", "rebuild-target.bst"], strict))
    result.assert_success()

    built_elements = result.get_built_elements()

    assert "rebuild-target.bst" in built_elements
    if strict == "strict":
        assert "target.bst" in built_elements
    else:
        assert "target.bst" not in built_elements


# Test that a cached artifact matching the strict cache key is preferred
# to a more recent artifact matching only the weak cache key.
@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.parametrize("strict", ["strict", "non-strict"])
def test_modify_and_revert(datafiles, cli, strict):
    project = str(datafiles)

    # First build target and dependencies
    result = cli.run(project=project, args=["build", "target.bst"])
    result.assert_success()

    # Remember cache key of first build
    target_cache_key = cli.get_element_key(project, "target.bst")

    # Modify dependency
    new_header_path = os.path.join(project, "files", "dev-files", "usr", "include", "new.h")
    with open(new_header_path, "w") as f:
        f.write("#define NEW")

    # Trigger rebuild. This will also rebuild the unmodified target as this
    # follows a strict build plan.
    result = cli.run(project=project, args=["build", "target.bst"])
    result.assert_success()

    assert "target.bst" in result.get_built_elements()
    assert cli.get_element_key(project, "target.bst") != target_cache_key

    # Revert previous modification in dependency
    os.unlink(new_header_path)

    # Rebuild again, everything should be cached.
    result = cli.run(project=project, args=["build", "target.bst"])
    result.assert_success()
    assert len(result.get_built_elements()) == 0

    # Verify that cache key now again matches the first build in both
    # strict and non-strict mode.
    cli.configure({"projects": {"test": {"strict": strict == "strict"}}})
    assert cli.get_element_key(project, "target.bst") == target_cache_key
