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

import os

import pytest
from buildstream._project import Project

from buildstream import _yaml
from buildstream.testing.runcli import cli  # pylint: disable=unused-import
from tests.testutils import dummy_context

from tests.testutils.artifactshare import create_dummy_artifact_share


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


@pytest.mark.datafiles(DATA_DIR)
def test_artifact_cache_with_missing_capabilities_is_skipped(cli, tmpdir, datafiles):
    project_dir = str(datafiles)

    # Set up an artifact cache.
    with create_dummy_artifact_share() as share:
        # Configure artifact share
        cache_dir = os.path.join(str(tmpdir), "cache")
        user_config_file = str(tmpdir.join("buildstream.conf"))
        user_config = {
            "scheduler": {"pushers": 1},
            "source-caches": {"servers": [{"url": share.repo,}]},
            "cachedir": cache_dir,
        }
        _yaml.roundtrip_dump(user_config, file=user_config_file)

        with dummy_context(config=user_config_file) as context:
            # Load the project
            project = Project(project_dir, context)
            project.ensure_fully_loaded()

            # Initialize remotes
            context.initialize_remotes(True, True, None, None)

            # Create a local artifact cache handle
            sourcecache = context.sourcecache

            assert (
                not sourcecache.has_fetch_remotes()
            ), "System didn't realize the source cache didn't support BuildStream"
