from __future__ import annotations

from pathlib import Path

import pytest

from sync_state_machine.common.binding import BindingManager
from sync_state_machine.common.collection import DataCollection
from sync_state_machine.common.persistence import PersistenceBackend
from sync_state_machine.common.sqlite_backend import SQLitePersistenceBackend
from tests.fixtures.mock_domain import build_project_node, register_test_domain


@pytest.mark.asyncio
async def test_scope_partitioning_and_copy_between_scopes(tmp_path: Path) -> None:
    register_test_domain()

    db_path = tmp_path / "scope_partitioning.db"
    persistence = SQLitePersistenceBackend(str(db_path))
    await persistence.initialize()

    global_collection = DataCollection("local", scope="global", persistence=persistence, auto_persist=False)
    global_node = build_project_node("node-global-1", "project-global-1", name="Global Project", code="GP-1")
    await global_collection.add(global_node)
    await global_collection.persist()

    global_bindings = BindingManager(persistence, auto_persist=False, scope="global")
    await global_bindings.bind("test_project", global_node.node_id, "remote-node-1")
    await global_bindings.persist()

    target_scope = "project_id:abc"
    await persistence.copy_nodes_between_scopes(
        collection_id="local",
        source_scope="global",
        target_scope=target_scope,
        node_types=["test_project"],
    )
    await persistence.copy_bindings_between_scopes(
        source_scope="global",
        target_scope=target_scope,
        node_types=["test_project"],
    )

    scoped_collection = DataCollection("local", scope=target_scope, persistence=persistence, auto_persist=False)
    await scoped_collection.load_from_persistence()
    scoped_nodes = scoped_collection.filter(node_type="test_project")
    assert len(scoped_nodes) == 1
    assert scoped_nodes[0].data_id == "project-global-1"

    scoped_bindings = BindingManager(persistence, auto_persist=False, scope=target_scope)
    await scoped_bindings.load_from_persistence("test_project")
    assert await scoped_bindings.get_remote_id("test_project", "node-global-1") == "remote-node-1"

    reloaded_global = DataCollection("local", scope="global", persistence=persistence, auto_persist=False)
    await reloaded_global.load_from_persistence()
    assert len(reloaded_global.filter(node_type="test_project")) == 1

    await persistence.close()