# Copyright (C) 2019-2022  The Software Heritage developers
# See the AUTHORS file at the top-level directory of this distribution
# License: GNU General Public License version 3, or any later version
# See top-level LICENSE file for more information

from functools import partial
from os import environ

import pytest
from pytest_postgresql import factories

from swh.core.db.db_utils import initialize_database_for_module
from swh.storage import get_storage
from swh.storage.postgresql.storage import Storage as StorageDatastore
from swh.storage.tests.storage_data import StorageData

environ["LC_ALL"] = "C.UTF-8"


swh_storage_postgresql_proc = factories.postgresql_proc(
    load=[
        partial(
            initialize_database_for_module,
            modname="storage",
            version=StorageDatastore.current_version,
        )
    ],
)


swh_storage_postgresql = factories.postgresql(
    "swh_storage_postgresql_proc",
)


@pytest.fixture
def swh_storage_backend_config(swh_storage_postgresql):
    """Basic pg storage configuration with no journal collaborator
    (to avoid pulling optional dependency on clients of this fixture)

    """
    yield {
        "cls": "postgresql",
        "db": swh_storage_postgresql.dsn,
        "objstorage": {"cls": "memory"},
        "check_config": {"check_write": True},
    }


@pytest.fixture
def swh_storage_backend(swh_storage_backend_config):
    """
    By default, this fixture aliases ``swh_storage``. However, when ``swh_storage``
    is overridden to be a proxy storage, this fixture returns the storage instance
    behind all proxies.

    This is useful to introspect the state of backends from proxy tests"""
    return get_storage(**swh_storage_backend_config)


@pytest.fixture
def swh_storage(swh_storage_backend):
    return swh_storage_backend


@pytest.fixture
def sample_data() -> StorageData:
    """Pre-defined sample storage object data to manipulate

    Returns:
        StorageData whose attribute keys are data model objects. Either multiple
        objects: contents, directories, revisions, releases, ... or simple ones:
        content, directory, revision, release, ...

    """
    return StorageData()
