import asyncio
import os
import time
from pathlib import Path

import pytest
import safe_radix32
from clarabot_crypto.group_config.block import GroupConfigBlockFlags, GroupConfigBlockMemberFlags
from clarabot_crypto.keyring.adhoc import AdhocKeyring
from clarabot_crypto.keyring.room import RoomKeyring
from clarabot_nano_common.common.protocol.errors import (
    NANO_REQUEST_ERROR_HANDLER_TARGET_NOT_FOUND,
    NANO_REQUEST_ERROR_HANDLER_BAD_REQUEST,
    NANO_REQUEST_ERROR_INTER_NANO_ERROR,
    NANO_REQUEST_ERROR_HANDLER_DENIED,
)
from clarabot_nano_common.utility.serialize import msgpack_dumps

from clarabot_nano.utility import parse_environment_flag
from clarabot_nano_tests.gateway.inter.utility import run_nano_setup_drive, check_fs_recursive
from clarabot_nano_tests.testing.client.manager import GraphQLClientManager
from clarabot_nano_tests.testing.core.common import clear_nano_slots
from clarabot_nano_tests.testing.file import temp_path
from clarabot_nano_tests.testing.server.manager import DevServerManager


@pytest.mark.skipif(parse_environment_flag("CBNANO_TEST_WITHOUT_SERVER"), reason="server-dependant tests disabled")
@pytest.mark.asyncio
async def test_gateway_inter_copy(
    tmpdir,
    reset_user_app_dirs,
    reset_user_app_dirs_override2,
    dev_nano_root_dir,
    testing_server_manager: DevServerManager,
    testing_server_user0,
    testing_client_manager: GraphQLClientManager,
    testing_server_reset_data,
):
    u0_id_sr32 = safe_radix32.encode_fw(testing_server_user0["account_id"])
    u0_kr = testing_server_user0["_acc_kr"]
    await clear_nano_slots(testing_server_manager, [testing_server_user0["account_id"]])

    u1_data = testing_server_reset_data["user_accounts"][1]
    u2_data = testing_server_reset_data["user_accounts"][2]  # NOTE: has nano license as well
    u3_data = testing_server_reset_data["user_accounts"][3]

    u0_rooms = [testing_server_user0["rooms"][i] for i in range(4)]
    u2_room = u2_data["rooms"][0]

    invalid_room_id = safe_radix32.encode_fw(u0_rooms[-1]["id"])  # NOTE: not actually invalid, but unused
    session = await testing_server_manager.session()  # debug client session

    u0_drive0, u0_drive1 = [Path(str(temp_path(tmpdir))) for _ in range(2)]
    u2_drive0 = Path(str(temp_path(tmpdir)))
    for dp in [u0_drive0, u0_drive1, u2_drive0]:
        os.makedirs(dp)

    u1wsc = await testing_client_manager.create_logged_in_wsc(u1_data)
    u3wsc = await testing_client_manager.create_logged_in_wsc(u3_data)

    async with run_nano_setup_drive(
        testing_server_manager,
        testing_client_manager,
        reset_user_app_dirs,
        dev_nano_root_dir,
        testing_server_user0,
        u0_drive0,
        u0_rooms[0],
    ) as (u0wsc, u0a_sess, u0mut_name, u0nano_id):
        async with run_nano_setup_drive(
            testing_server_manager,
            testing_client_manager,
            reset_user_app_dirs_override2[1:],
            dev_nano_root_dir,
            u2_data,
            u2_drive0,
            u2_room,
            extra_env={"CBNANO_USER_DIR_OVERRIDE": reset_user_app_dirs_override2[0]},
        ) as (u2wsc, u2a_sess, u2mut_name, u2nano_id):
            u2room_id = safe_radix32.encode_fw(u2_room["id"])
            await asyncio.sleep(1.0)

            # setup access control for testing
            # drive0 by u0:
            #   - accessible by u1 with write, u3 as read
            _x = GroupConfigBlockMemberFlags
            await testing_client_manager.nano_request_response(
                msgpack_dumps(
                    await testing_client_manager.prepare_request_with_mutation_id(
                        {
                            "type": "ROOM-CFG",
                            "room_id": safe_radix32.encode_fw(u0_rooms[0]["id"]),
                            "member_flags": {
                                safe_radix32.encode_fw(u1_data["account_id"]): _x.ACTIVE | _x.DRIVE_WRITE,
                                safe_radix32.encode_fw(u2_data["account_id"]): _x.ACTIVE_NEGATE,
                                safe_radix32.encode_fw(u3_data["account_id"]): _x.ACTIVE | _x.DRIVE_WRITE_NEGATE,
                            },
                            "group_flags": GroupConfigBlockFlags.ALLOW_ANONYMOUS_NEGATE,
                        },
                        "dbg_inter_copy_u0",
                        u0_rooms[0]["id"],
                        None,
                        u0wsc,
                        u0_kr,
                        u0_kr,
                    )
                ),
                u0_rooms[0]["id"],
                None,
                u0wsc,
                u0_kr,
                u0_kr,
            )
            # drive1 by u2:
            #   - accessible by u1 with write, u0 and u3 as read
            await testing_client_manager.nano_request_response(
                msgpack_dumps(
                    await testing_client_manager.prepare_request_with_mutation_id(
                        {
                            "type": "ROOM-CFG",
                            "room_id": safe_radix32.encode_fw(u2_room["id"]),
                            "member_flags": {
                                u0_id_sr32: _x.ACTIVE | _x.DRIVE_WRITE_NEGATE,
                                safe_radix32.encode_fw(u1_data["account_id"]): _x.ACTIVE | _x.DRIVE_WRITE,
                                safe_radix32.encode_fw(u3_data["account_id"]): _x.ACTIVE | _x.DRIVE_WRITE_NEGATE,
                            },
                            "group_flags": GroupConfigBlockFlags.ALLOW_ANONYMOUS_NEGATE,
                        },
                        "dbg_inter_copy_u2",
                        u2_room["id"],
                        None,
                        u2wsc,
                        u2_data["_acc_kr"],
                        u2_data["_acc_kr"],
                    )
                ),
                u2_room["id"],
                None,
                u2wsc,
                u2_data["_acc_kr"],
                u2_data["_acc_kr"],
            )
            await asyncio.sleep(1.0)

            async def _describe_until_not_done(*args, timeout=10.0):
                job_ = None
                for _ in range(int(timeout * 4)):
                    job_ = await testing_client_manager.describe_inter_job(*args)
                    if job_.get("state") not in ("waiting", "running"):
                        return job_
                    await asyncio.sleep(0.25)
                assert False, f"timeout {job_}"

            await testing_client_manager.describe_inter_job(
                1,
                u2_room["id"],
                u1wsc,
                u1_data["_acc_kr"],
                u2_data["_acc_kr"],
                u2_room["_room_kr"],
                error=NANO_REQUEST_ERROR_HANDLER_TARGET_NOT_FOUND,
            )
            lst = await testing_client_manager.list_inter_jobs(
                u2_room["id"],
                u1wsc,
                u1_data["_acc_kr"],
                u2_data["_acc_kr"],
                u2_room["_room_kr"],
            )
            assert not lst, str(lst)
            for req in [
                {},
                {"drive_path": "404"},
                {"drive_path": "404", "remote_room_id": u0_rooms[0]["id"]},
                {"drive_path": "404", "remote_room_id": safe_radix32.encode_fw(u0_rooms[0]["id"])},
                {
                    "drive_path": "404",
                    "remote_room_id": safe_radix32.encode_fw(u0_rooms[0]["id"]),
                    "remote_path": "r404",
                    "remote_items": [],
                    # missing adhoc token
                },
            ]:
                await testing_client_manager.create_inter_copy(
                    req,
                    u2_room["id"],
                    "inter_copy_u1_to_u2",
                    u1wsc,
                    u1_data["_acc_kr"],
                    u2_data["_acc_kr"],
                    u2_room["_room_kr"],
                    error=NANO_REQUEST_ERROR_HANDLER_BAD_REQUEST,
                )
            await testing_client_manager.create_inter_copy(
                {
                    "drive_path": "404",
                    "remote_room_id": safe_radix32.encode_fw(u0_rooms[0]["id"]),
                    "remote_path": "r404",
                    "remote_items": [],
                    "adhoc_token": "invalid.adhoc_token",
                    "adhoc_keys": {AdhocKeyring.KEY1: b"x" * AdhocKeyring.VALID_KEY_LENGTH_MAP[AdhocKeyring.KEY1]},
                },
                u2_room["id"],
                "inter_copy_u1_to_u2",
                u1wsc,
                u1_data["_acc_kr"],
                u2_data["_acc_kr"],
                u2_room["_room_kr"],
                error=NANO_REQUEST_ERROR_INTER_NANO_ERROR,  # remote drive inaccessible (invalid adhoc-token)
            )
            # test self copy need no adhoc from non-owner
            await testing_client_manager.create_inter_copy(
                {
                    "drive_path": "404",
                    "remote_room_id": safe_radix32.encode_fw(u2_room["id"]),
                    "remote_path": "r404",
                    "remote_items": [],
                },
                u2_room["id"],
                "inter_copy_u1_to_u2",
                u1wsc,
                u1_data["_acc_kr"],
                u2_data["_acc_kr"],
                u2_room["_room_kr"],
                error=NANO_REQUEST_ERROR_INTER_NANO_ERROR,  # local path missing
            )

            (u0_drive0 / "a_file0").write_bytes(os.urandom(16))
            (u0_drive0 / "a_file1").write_bytes(os.urandom(16))
            (u0_drive0 / "a_file2").write_bytes(os.urandom(16))
            a_file0_aht, a_file0_aht_kr = await testing_client_manager.create_adhoc_fs(
                "a_file0",
                u0_rooms[0]["id"],
                "inter_copy_u1_to_u0",
                u1wsc,
                u1_data["_acc_kr"],
                u0_kr,
                u0_rooms[0]["_room_kr"],
            )
            await testing_client_manager.create_inter_copy(
                {
                    "drive_path": "404",
                    "remote_room_id": safe_radix32.encode_fw(u0_rooms[0]["id"]),
                    "remote_path": "",
                    "remote_items": [],
                    # missing adhoc token
                },
                u2_room["id"],
                "inter_copy_u1_to_u2",
                u1wsc,
                u1_data["_acc_kr"],
                u2_data["_acc_kr"],
                u2_room["_room_kr"],
                error=NANO_REQUEST_ERROR_HANDLER_BAD_REQUEST,  # adhoc token required
            )
            await testing_client_manager.create_inter_copy(
                {
                    "drive_path": "404",
                    "remote_room_id": safe_radix32.encode_fw(u0_rooms[0]["id"]),
                    "remote_path": "",
                    "remote_items": [],
                    "room_keys": {RoomKeyring.PINNED: u0_rooms[0]["_room_kr"].get_key(RoomKeyring.PINNED)},
                },
                u2_room["id"],
                "inter_copy_u1_to_u2",
                u1wsc,
                u1_data["_acc_kr"],
                u2_data["_acc_kr"],
                u2_room["_room_kr"],
                error=NANO_REQUEST_ERROR_INTER_NANO_ERROR,  # room is not publicly accessible
            )
            await testing_client_manager.create_inter_copy(
                {
                    "drive_path": "404",
                    "remote_room_id": safe_radix32.encode_fw(u0_rooms[0]["id"]),
                    "remote_path": "",
                    "remote_items": [],
                },
                u2_room["id"],
                "inter_copy_u2_to_u2",
                u2wsc,
                u2_data["_acc_kr"],
                u2_data["_acc_kr"],
                error=NANO_REQUEST_ERROR_INTER_NANO_ERROR,  # local path missing (adhoc token optional for owner)
            )
            await testing_client_manager.create_inter_copy(
                {
                    "drive_path": "404",
                    "remote_room_id": safe_radix32.encode_fw(u0_rooms[0]["id"]),
                    "remote_path": "",
                    "remote_items": [],
                    "room_keys": {RoomKeyring.PINNED: u0_rooms[0]["_room_kr"].get_key(RoomKeyring.PINNED)},
                    "adhoc_token": a_file0_aht,
                    "adhoc_keys": {AdhocKeyring.KEY1: a_file0_aht_kr.get_key(AdhocKeyring.KEY1)},
                },
                u2_room["id"],
                "inter_copy_u1_to_u2",
                u1wsc,
                u1_data["_acc_kr"],
                u2_data["_acc_kr"],
                u2_room["_room_kr"],
                error=NANO_REQUEST_ERROR_HANDLER_BAD_REQUEST,  # adhoc-token and room_keys are exclusive
            )
            await testing_client_manager.create_inter_copy(
                {
                    "drive_path": "404",
                    "remote_room_id": safe_radix32.encode_fw(u0_rooms[0]["id"]),
                    "remote_path": "",
                    "remote_items": [],
                    "adhoc_token": a_file0_aht,
                    "adhoc_keys": {AdhocKeyring.KEY1: a_file0_aht_kr.get_key(AdhocKeyring.KEY1)},
                },
                u2_room["id"],
                "inter_copy_u1_to_u2",
                u1wsc,
                u1_data["_acc_kr"],
                u2_data["_acc_kr"],
                u2_room["_room_kr"],
                error=NANO_REQUEST_ERROR_INTER_NANO_ERROR,  # local path missing
            )
            await testing_client_manager.create_inter_copy(
                {
                    "drive_path": "",
                    "remote_room_id": safe_radix32.encode_fw(u0_rooms[0]["id"]),
                    "remote_path": "",
                    "remote_items": "all",
                    "adhoc_token": a_file0_aht,
                    "adhoc_keys": {AdhocKeyring.KEY1: a_file0_aht_kr.get_key(AdhocKeyring.KEY1)},
                },
                u2_room["id"],
                "inter_copy_u1_to_u2",
                u1wsc,
                u1_data["_acc_kr"],
                u2_data["_acc_kr"],
                u2_room["_room_kr"],
                error=NANO_REQUEST_ERROR_HANDLER_BAD_REQUEST,  # remote_items invalid
            )
            copy0_id = await testing_client_manager.create_inter_copy(
                {
                    "drive_path": "",
                    "remote_room_id": safe_radix32.encode_fw(u0_rooms[0]["id"]),
                    "remote_path": "",
                    "remote_items": None,
                    "adhoc_token": a_file0_aht,
                    "adhoc_keys": {AdhocKeyring.KEY1: a_file0_aht_kr.get_key(AdhocKeyring.KEY1)},
                },
                u2_room["id"],
                "inter_copy_u1_to_u2",
                u1wsc,
                u1_data["_acc_kr"],
                u2_data["_acc_kr"],
                u2_room["_room_kr"],
            )
            copy0_job = await _describe_until_not_done(
                copy0_id, u2_room["id"], u1wsc, u1_data["_acc_kr"], u2_data["_acc_kr"], u2_room["_room_kr"]
            )
            assert copy0_job["state"] == "completed"
            check_fs_recursive(u0_drive0 / "a_file0", u2_drive0 / "a_file0")

            a_file1_aht, a_file1_aht_kr = await testing_client_manager.create_adhoc_fs(
                "a_file1",
                u0_rooms[0]["id"],
                "inter_copy_u1_to_u0",
                u1wsc,
                u1_data["_acc_kr"],
                u0_kr,
                u0_rooms[0]["_room_kr"],
            )
            t = time.perf_counter()
            copy1_ids = []
            for _ in range(2):
                copy1_ids.append(
                    await testing_client_manager.create_inter_copy(
                        {
                            "drive_path": "",
                            "remote_room_id": safe_radix32.encode_fw(u0_rooms[0]["id"]),
                            "remote_path": "",
                            "remote_items": None,
                            "adhoc_token": a_file1_aht,
                            "adhoc_keys": {AdhocKeyring.KEY1: a_file1_aht_kr.get_key(AdhocKeyring.KEY1)},
                        },
                        u2_room["id"],
                        "inter_copy_u1_to_u2",
                        u1wsc,
                        u1_data["_acc_kr"],
                        u2_data["_acc_kr"],
                        u2_room["_room_kr"],
                    )
                )
            copy1_id = copy1_ids[0]
            assert time.perf_counter() - t < 0.5
            await testing_client_manager.delete_inter_job(
                copy1_id,
                u2_room["id"],
                "inter_copy_u3_to_u2",
                u3wsc,
                u3_data["_acc_kr"],
                u2_data["_acc_kr"],
                u2_room["_room_kr"],
                error=NANO_REQUEST_ERROR_HANDLER_DENIED,
            )
            lst = await testing_client_manager.list_inter_jobs(
                u2_room["id"],
                u1wsc,
                u1_data["_acc_kr"],
                u2_data["_acc_kr"],
                u2_room["_room_kr"],
            )
            assert (
                len(lst) == 2
                and lst[0]["id"] == copy1_ids[0]
                and lst[0]["state"] == "running"
                and lst[1]["id"] == copy1_ids[1]
                and lst[1]["state"] == "waiting"
            ), str(lst)
            for copy_id in reversed(copy1_ids):
                await testing_client_manager.delete_inter_job(
                    copy_id,
                    u2_room["id"],
                    "inter_copy_u1_to_u2",
                    u1wsc,
                    u1_data["_acc_kr"],
                    u2_data["_acc_kr"],
                    u2_room["_room_kr"],
                )
            lst = await testing_client_manager.list_inter_jobs(
                u2_room["id"],
                u1wsc,
                u1_data["_acc_kr"],
                u2_data["_acc_kr"],
                u2_room["_room_kr"],
            )
            assert len(lst) == 0, str(lst)
            copy1_job = await testing_client_manager.describe_inter_job(
                copy1_ids[1],
                u2_room["id"],
                u1wsc,
                u1_data["_acc_kr"],
                u2_data["_acc_kr"],
                u2_room["_room_kr"],
            )
            assert copy1_job.get("state") == "cancelled", str(copy1_job)
            assert time.perf_counter() - t < 0.8
            for tmp_id in copy1_ids:
                copy1_job = await _describe_until_not_done(
                    tmp_id, u2_room["id"], u1wsc, u1_data["_acc_kr"], u2_data["_acc_kr"], u2_room["_room_kr"]
                )
                assert copy1_job.get("state") == "cancelled", str(copy1_job)

            # test missing write permission
            await testing_client_manager.describe_inter_job(
                copy1_id,
                u2_room["id"],
                u3wsc,
                u3_data["_acc_kr"],
                u2_data["_acc_kr"],
                u2_room["_room_kr"],
                error=NANO_REQUEST_ERROR_HANDLER_DENIED,
            )

            assert {item.name for item in u2_drive0.iterdir()} == {"a_file0"}
            (u2_drive0 / "trg3").mkdir()
            (u0_drive0 / "a_dir0").mkdir()
            (u0_drive0 / "a_dir0" / "a_file5").write_bytes(os.urandom(20))
            (u0_drive0 / "a_dir0" / "a_file7").write_bytes(os.urandom(22))
            (u0_drive0 / "a_dir0" / "a_dir2").mkdir()
            (u0_drive0 / "a_dir0" / "a_dir2" / "a_file7").write_bytes(os.urandom(20))
            (u0_drive0 / "a_dir0" / "a_dir2" / "a_dir3").mkdir()
            (u0_drive0 / "a_dir0" / "a_dir2" / "a_dir3" / "a_file8").write_bytes(os.urandom(23))
            (u0_drive0 / "a_dir1").mkdir()
            (u0_drive0 / "a_dir1" / "a_file6").write_bytes(os.urandom(21))
            a_root_aht, a_root_aht_kr = await testing_client_manager.create_adhoc_fs(
                "",
                u0_rooms[0]["id"],
                "inter_copy_u1_to_u0",
                u1wsc,
                u1_data["_acc_kr"],
                u0_kr,
                u0_rooms[0]["_room_kr"],
            )
            copy2_id = await testing_client_manager.create_inter_copy(
                {
                    "drive_path": "trg3",
                    "remote_room_id": safe_radix32.encode_fw(u0_rooms[0]["id"]),
                    "remote_path": "a_dir0",
                    "remote_items": ["a_dir2", "a_file5"],
                    "adhoc_token": a_root_aht,
                    "adhoc_keys": {AdhocKeyring.KEY1: a_root_aht_kr.get_key(AdhocKeyring.KEY1)},
                },
                u2_room["id"],
                "inter_copy_u1_to_u2",
                u1wsc,
                u1_data["_acc_kr"],
                u2_data["_acc_kr"],
                u2_room["_room_kr"],
            )
            copy2_job = await _describe_until_not_done(
                copy2_id, u2_room["id"], u1wsc, u1_data["_acc_kr"], u2_data["_acc_kr"], u2_room["_room_kr"]
            )
            assert copy2_job["state"] == "completed"
            check_fs_recursive(u0_drive0 / "a_dir0" / "a_dir2", u2_drive0 / "trg3" / "a_dir2")
            check_fs_recursive(u0_drive0 / "a_dir0" / "a_file5", u2_drive0 / "trg3" / "a_file5")

            (u2_drive0 / "trg4").mkdir()
            copy3_id = await testing_client_manager.create_inter_copy(
                {
                    "drive_path": "trg4",
                    "remote_room_id": safe_radix32.encode_fw(u0_rooms[0]["id"]),
                    "remote_path": "a_dir0",
                    "remote_items": [],
                    "adhoc_token": a_root_aht,
                    "adhoc_keys": {AdhocKeyring.KEY1: a_root_aht_kr.get_key(AdhocKeyring.KEY1)},
                },
                u2_room["id"],
                "inter_copy_u1_to_u2",
                u1wsc,
                u1_data["_acc_kr"],
                u2_data["_acc_kr"],
                u2_room["_room_kr"],
            )
            copy3_job = await _describe_until_not_done(
                copy3_id, u2_room["id"], u1wsc, u1_data["_acc_kr"], u2_data["_acc_kr"], u2_room["_room_kr"]
            )
            assert copy3_job["state"] == "completed"
            check_fs_recursive(u0_drive0 / "a_dir0", u2_drive0 / "trg4")

            (u2_drive0 / "trg5").mkdir()
            copy4_id = await testing_client_manager.create_inter_copy(
                {
                    "drive_path": "trg5",
                    "remote_room_id": safe_radix32.encode_fw(u0_rooms[0]["id"]),
                    "remote_path": "a_dir0",
                    "remote_items": None,
                    "adhoc_token": a_root_aht,
                    "adhoc_keys": {AdhocKeyring.KEY1: a_root_aht_kr.get_key(AdhocKeyring.KEY1)},
                },
                u2_room["id"],
                "inter_copy_u1_to_u2",
                u1wsc,
                u1_data["_acc_kr"],
                u2_data["_acc_kr"],
                u2_room["_room_kr"],
            )
            copy4_job = await _describe_until_not_done(
                copy4_id, u2_room["id"], u1wsc, u1_data["_acc_kr"], u2_data["_acc_kr"], u2_room["_room_kr"]
            )
            assert copy4_job["state"] == "completed"
            check_fs_recursive(u0_drive0 / "a_dir0", u2_drive0 / "trg5" / "a_dir0")

            # == self-copy ==
            await testing_client_manager.create_inter_copy(
                {
                    "drive_path": "trg5",
                    "remote_room_id": safe_radix32.encode_fw(u2_room["id"]),
                    "remote_path": "trg5",
                    "remote_items": None,
                    "room_keys": {RoomKeyring.PINNED: u2_room["_room_kr"].get_key(RoomKeyring.PINNED)},
                },
                u2_room["id"],
                "inter_copy_u1_to_u2",
                u1wsc,
                u1_data["_acc_kr"],
                u2_data["_acc_kr"],
                u2_room["_room_kr"],
                error=NANO_REQUEST_ERROR_HANDLER_BAD_REQUEST,  # room_keys forbidden for self case
            )
            # test src-trg containment check
            copy5_id = await testing_client_manager.create_inter_copy(
                {
                    "drive_path": "trg5",
                    "remote_room_id": safe_radix32.encode_fw(u2_room["id"]),
                    "remote_path": "trg5",
                    "remote_items": None,
                },
                u2_room["id"],
                "inter_copy_u1_to_u2",
                u1wsc,
                u1_data["_acc_kr"],
                u2_data["_acc_kr"],
                u2_room["_room_kr"],
            )
            copy5_job = await _describe_until_not_done(
                copy5_id, u2_room["id"], u1wsc, u1_data["_acc_kr"], u2_data["_acc_kr"], u2_room["_room_kr"]
            )
            assert copy5_job["state"] == "failed"
            (u2_drive0 / "trg5/asd").mkdir()
            copy6_id = await testing_client_manager.create_inter_copy(
                {
                    "drive_path": "trg5/asd",
                    "remote_room_id": safe_radix32.encode_fw(u2_room["id"]),
                    "remote_path": "trg5",
                    "remote_items": None,
                },
                u2_room["id"],
                "inter_copy_u1_to_u2",
                u1wsc,
                u1_data["_acc_kr"],
                u2_data["_acc_kr"],
                u2_room["_room_kr"],
            )
            copy6_job = await _describe_until_not_done(
                copy6_id, u2_room["id"], u1wsc, u1_data["_acc_kr"], u2_data["_acc_kr"], u2_room["_room_kr"]
            )
            assert copy6_job["state"] == "failed"
            copy7_id = await testing_client_manager.create_inter_copy(
                {
                    "drive_path": "",
                    "remote_room_id": safe_radix32.encode_fw(u2_room["id"]),
                    "remote_path": "trg5",
                    "remote_items": None,
                },
                u2_room["id"],
                "inter_copy_u1_to_u2",
                u1wsc,
                u1_data["_acc_kr"],
                u2_data["_acc_kr"],
                u2_room["_room_kr"],
            )
            copy7_job = await _describe_until_not_done(
                copy7_id, u2_room["id"], u1wsc, u1_data["_acc_kr"], u2_data["_acc_kr"], u2_room["_room_kr"]
            )
            assert copy7_job["state"] == "failed"

            copy8_id = await testing_client_manager.create_inter_copy(
                {
                    "drive_path": "",
                    "remote_room_id": safe_radix32.encode_fw(u2_room["id"]),
                    "remote_path": "trg5",
                    "remote_items": ["a_dir0"],
                },
                u2_room["id"],
                "inter_copy_u1_to_u2",
                u1wsc,
                u1_data["_acc_kr"],
                u2_data["_acc_kr"],
                u2_room["_room_kr"],
            )
            copy8_job = await _describe_until_not_done(
                copy8_id, u2_room["id"], u1wsc, u1_data["_acc_kr"], u2_data["_acc_kr"], u2_room["_room_kr"]
            )
            assert copy8_job["state"] == "completed"
            check_fs_recursive(u0_drive0 / "a_dir0", u2_drive0 / "a_dir0")
