"""D-G26 tests — ``client.rename_vm`` through the SDK.

Round-trips rename over the fake hypervisor: the ``vm_id`` is stable, the
cached desired-state spec + observed status both reflect the new name, and the
contract errors (running / name-taken) propagate.
"""

from __future__ import annotations

import pytest
from mgf.vm.core.contracts import VmSpec
from mgf.vm.core.exceptions import DomainAlreadyExistsError, DomainStateInvalid
from mgf.vm.core.fakes.hypervisor import FakeHypervisorBackend

from mgf.vm.sdk.client import VmManagerClient
from mgf.vm.sdk.transport.inprocess import InProcessTransport


def _spec(name: str) -> VmSpec:
    return VmSpec(name=name, cpu=2, memory_bytes=2 << 30)


def _client() -> VmManagerClient:
    return VmManagerClient(InProcessTransport.from_adapters(FakeHypervisorBackend()))


def test_rename_preserves_id_and_updates_name() -> None:
    client = _client()
    vm_id = client.create_vm(_spec("before")).vm_id
    client.rename_vm(vm_id, "after")
    vm = client.get_vm(vm_id)
    assert vm.vm_id == vm_id  # identity stable
    assert vm.spec.name == "after"  # cached spec re-synced (the canonical name)


def test_rename_running_vm_raises_state_invalid() -> None:
    client = _client()
    vm_id = client.create_vm(_spec("run")).vm_id
    client.start_vm(vm_id)
    with pytest.raises(DomainStateInvalid):
        client.rename_vm(vm_id, "run-renamed")


def test_rename_to_taken_name_raises_already_exists() -> None:
    client = _client()
    vm_id = client.create_vm(_spec("one")).vm_id
    client.create_vm(_spec("two"))
    with pytest.raises(DomainAlreadyExistsError):
        client.rename_vm(vm_id, "two")
