from dcim.models import Device
from extras.scripts import Script, ObjectVar

class ReplaceDevice(Script):
    '''
    Replace a device with another. Used for instance to upgrade classroom PCs.
    This renames the new device, switches existing primary IPs from the old device to it and sets it active.
    The old device is unnamed and set as inventory.
    '''

    class Meta:
        name = 'Replace device'
        description = 'Replace a device with another, preserving the name and primary IPs'
        commit_default = False
        scheduling_enabled = False

    old = ObjectVar(model=Device, label='Old device')
    new = ObjectVar(model=Device, label='New device')

    def run(self, data, commit):
        old = data['old']
        new = data['new']

        new.name = old.name
        new.status = 'active'

        old.name = None
        if old.status == 'active': # could be failed
            old.status = 'inventory' 

        if ip4 := old.primary_ip4:
            old.primary_ip4 = None
            old.full_clean()
            old.save()

            old_iface = ip4.interface.get()
            new_iface = new.interfaces.get(name=old_iface.name)
            ip4.assigned_object = new_iface
            ip4.full_clean()
            ip4.save()

            new.primary_ip4 = ip4
            self.log_info(f'set {ip4} as primary IP for new {new.name} ({new.asset_tag})')

        if ip6 := old.primary_ip6:
            old.primary_ip6 = None
            old.full_clean()
            old.save()

            old_iface = ip6.interface.get()
            new_iface = new.interfaces.get(name=old_iface.name)
            ip6.assigned_object = new_iface
            ip6.full_clean()
            ip6.save()

            new.primary_ip6 = ip6
            self.log_info(f'set {ip6} as primary IP for new {new.name} ({new.asset_tag})')

        new.full_clean()
        new.save()

        self.log_success(f'replaced device {new.name}: {old.asset_tag} → {new.asset_tag}')