import sqlalchemy as sa
from sqlalchemy.exc import IntegrityError
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship

from middlewared.sqlalchemy import EncryptedText, JSON, Time

import middlewared.plugins.datastore  # noqa
import middlewared.plugins.datastore.connection  # noqa
import middlewared.plugins.datastore.schema  # noqa
import middlewared.plugins.datastore.util  # noqa

from middlewared.pytest.unit.helpers import load_compound_service
from middlewared.pytest.unit.middleware import Middleware

DatastoreService = load_compound_service("datastore")

Model = declarative_base()


@asynccontextmanager
async def datastore_test():
    m = Middleware()
    with patch("middlewared.plugins.datastore.connection.FREENAS_DATABASE", ":memory:"):
        with patch("middlewared.plugins.datastore.schema.Model", Model):
            with patch("middlewared.plugins.datastore.util.Model", Model):
                ds = DatastoreService(m)
                await ds.setup()

                for part in ds.parts:
                    if hasattr(part, "connection"):
import pytest

import middlewared.plugins.zettarepl  # noqa
import middlewared.plugins.zettarepl_.util  # noqa

from middlewared.pytest.unit.helpers import load_compound_service

ZettareplService = load_compound_service("zettarepl")


@pytest.mark.parametrize(
    "source_datasets,target_dataset,reversed_source_datasets,reversed_target_dataset",
    [
        (["tank/work"], "backup/tank-work", ["backup/tank-work"], "tank/work"),
        (["tank/work/alice", "tank/work/bob"], "backup/tank-work",
         ["backup/tank-work/alice", "backup/tank-work/bob"], "tank/work"),
    ])
@pytest.mark.asyncio
async def test__reverse_source_target_datasets(source_datasets, target_dataset,
                                               reversed_source_datasets,
                                               reversed_target_dataset):
    zs = ZettareplService(None)
    assert await zs.reverse_source_target_datasets(
        source_datasets, target_dataset) == (
            reversed_source_datasets,
            reversed_target_dataset,
        )