

from engine.SystemLib import *
import subprocess
import os
import shutil


def ogNvramActiveEntry(*args):
    FUNCNAME = ogNvramActiveEntry.__name__
    NUMENTRY = None

    # Si se solicita, mostrar ayuda.
    if "help" in args:
        ogHelp(FUNCNAME, f"{FUNCNAME} [ Num_order_entry | Label_entry ]", f"{FUNCNAME} 2", f'{FUNCNAME} "Windows Boot Manager"')
        return
    
    # Error si no se recibe 1 parámetro.
    if len(args) != 1:
        ogRaiseError(OG_ERR_FORMAT, f"{FUNCNAME} [ Num_order_entry | Label_entry ]")
        return

    # Si no es equipo UEFI salir con error
    if not ogIsEfiActive():
        ogRaiseError(OG_ERR_NOTUEFI)
        return

    # Distingo si es número de orden o etiqueta
    if args[0].isdigit():
        NUMENTRY = subprocess.check_output(['efibootmgr', '-v']).decode().split()[0][4:8]
    else:
        NUMENTRY = subprocess.check_output(['efibootmgr', '-v']).decode().split()[0][4:8]

    if NUMENTRY == "":
        ogRaiseError(OG_ERR_NOTFOUND, f"NVRAM entry '{args[0]}'")
        return

    subprocess.run(['efibootmgr', '-a', '-b', NUMENTRY], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

def ogNvramAddEntry(*args):
    FUNCNAME = ogNvramAddEntry.__name__
    EFIDISK = None
    EFIPART = None
    BOOTLABEL = None
    BOOTLOADER = None
    ADDORDER = None

    # Si se solicita, mostrar ayuda.
    if "help" in args:
        ogHelp(FUNCNAME, f"{FUNCNAME} Str_label_entry Str_boot_loader [ Bool_add_bootorder ]", f"{FUNCNAME} 1 2 TRUE", f'{FUNCNAME} grub /EFI/grub/grubx64.efi TRUE', f'{FUNCNAME} Windows /EFI/Microsoft/Boot/bootmgfw.efi')
        return

    # Error si no se recibe 2 o 3 parámetros.
    if len(args) < 2 or len(args) > 3:
        ogRaiseError(OG_ERR_FORMAT, f"{FUNCNAME} Str_label_entry Str_boot_loader")
        return

    # Si no es equipo UEFI salir con error
    if not ogIsEfiActive():
        ogRaiseError(OG_ERR_NOTUEFI)
        return

    EFIDISK, EFIPART = ogGetEsp().split()
    if EFIPART == "":
        ogRaiseError(OG_ERR_NOTFOUND, "ESP")
        return

    # Recogemos parámetros
    # Distinguimos si es disco/partición o etiqueta/cargador
    if args[0].isdigit() and args[1].isdigit():
        BOOTLABEL = f"Part-{int(args[0]):02d}-{int(args[1]):02d}"
        BOOTLOADER = f"/EFI/{BOOTLABEL}/Boot/ogloader.efi"
    else:
        BOOTLABEL = args[0]
        BOOTLOADER = args[1]

    # Si existe entrada con la misma etiqueta la borramos
    ogNvramDeleteEntry(BOOTLABEL)

    subprocess.run(['efibootmgr', '-C', '-d', ogDiskToDev(EFIDISK), '-p', EFIPART, '-L', BOOTLABEL, '-l', BOOTLOADER], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

    # Incluimos la entrada en el orden de arranque (opcional)
    if len(args) == 3 and args[2].upper() == "TRUE":
        NUMENTRY = subprocess.check_output(['efibootmgr']).decode().split('\n')
        for entry in NUMENTRY:
            if entry.startswith(BOOTLABEL):
                NUMENTRY = entry[4:8]
                break
        ogNvramSetOrder(*ogNvramGetOrder().split(','), NUMENTRY)

def ogCopyEfiBootLoader():
    FUNCNAME = ogCopyEfiBootLoader.__name__
    # Si se solicita, mostrar ayuda.
    if "help" in args:
        ogHelp(FUNCNAME, f"{FUNCNAME} int_ndisk int_part", f"{FUNCNAME} 1 2")
        return
    
    # Error si no se reciben 2 parámetros.
    if len(args) != 2:
        ogRaiseError(OG_ERR_FORMAT, f"{FUNCNAME} int_ndisk int_part")
        return

    # Comprobamos que exista partición de sistema y la ESP
    MNTDIR = ogMount(args[0], args[1])
    if MNTDIR is None:
        ogRaiseError(OG_ERR_PARTITION, f"{DISK} {PART}")
        return

    EFIDIR = ogMount(ogGetEsp())
    if EFIDIR is None:
        ogRaiseError(OG_ERR_PARTITION, "ESP")
        return

    # Comprobamos que exista el cargador
    BOOTLABEL = f"Part-{int(args[0]):02d}-{int(args[1]):02d}"
    OSVERSION = ogGetOsVersion(args[0], args[1])
    LOADER = None
    for f in [f"{EFIDIR}/EFI/Microsoft/Boot/bootmgfw.efi", f"{EFIDIR}/EFI/{BOOTLABEL}/Boot/bootmgfw.efi"]:
        if os.path.isfile(f):
            LOADER = f
            break

    if LOADER is None:
        ogRaiseError(OG_ERR_NOTOS, f"{args[0]} {args[1]} ({OSVERSION}, EFI)")
        return

    # Si existe el directorio Boot lo borramos
    if os.path.isdir(f"{MNTDIR}/ogBoot"):
        shutil.rmtree(f"{MNTDIR}/ogBoot")

    DIRLOADER = os.path.realpath(os.path.join(os.path.dirname(LOADER), ".."))
    shutil.copytree(f"{DIRLOADER}/Boot", f"{MNTDIR}/ogBoot")

def ogNvramDeleteEntry(*args):
    FUNCNAME = ogNvramDeleteEntry.__name__
    NUMENTRY = None

    # Si se solicita, mostrar ayuda.
    if "help" in args:
        ogHelp(FUNCNAME, f"{FUNCNAME} [ Num_order_entry | Label_entry ]", f"{FUNCNAME} 2", f'{FUNCNAME} "Windows Boot Manager"')
        return

    # Error si no se recibe 1 parámetro.
    if len(args) != 1:
        ogRaiseError(OG_ERR_FORMAT, f"{FUNCNAME} [ Num_order_entry | Label_entry ]")
        return

    # Si no es equipo UEFI salir con error
    if not ogIsEfiActive():
        ogRaiseError(OG_ERR_NOTUEFI)
        return

    # Distingo si es número de orden o etiqueta
    if args[0].isdigit():
        NUMENTRY = subprocess.check_output(['efibootmgr']).decode().split('\n')
        for entry in NUMENTRY:
            if entry.startswith(args[0]):
                NUMENTRY = entry[4:8]
                break
    else:
        NUMENTRY = subprocess.check_output(['efibootmgr']).decode().split('\n')
        for entry in NUMENTRY:
            if entry.startswith(args[0]):
                NUMENTRY = entry[4:8]
                break

    if NUMENTRY == "":
        ogRaiseError(OG_ERR_NOTFOUND, f"NVRAM entry '{args[0]}'")
        return

    for n in NUMENTRY:
        subprocess.run(['efibootmgr', '-B', '-b', n], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

def ogNvramGetCurrent():
    FUNCNAME = ogNvramGetCurrent.__name__
    # Si se solicita, mostrar ayuda.
    if "help" in args:
        ogHelp(FUNCNAME, FUNCNAME, FUNCNAME)
        return
    
    # Si no es equipo UEFI salir con error
    if not ogIsEfiActive():
        ogRaiseError(OG_ERR_NOTUEFI)
        return

    output = subprocess.check_output(['efibootmgr']).decode().split('\n')
    bootentry = 99999
    for line in output:
        if "BootCurrent" in line:
            bootentry = line.split()[1]
        if bootentry in line:
            num_entry = line[4:8]
            label_entry = line[line.index(bootentry):]
            print(f"{num_entry} {label_entry}")

def ogNvramGetNext():
    # Si se solicita, mostrar ayuda.
    if "help" in args:
        ogHelp(FUNCNAME, FUNCNAME, FUNCNAME)
        return
    
    # Si no es equipo UEFI salir con error
    if not ogIsEfiActive():
        ogRaiseError(OG_ERR_NOTUEFI)
        return

    output = subprocess.check_output(['efibootmgr']).decode().split('\n')
    for line in output:
        if "BootNext" in line:
            bootnext = line.split()[1]
            return bootnext
    return None

def ogNvramGetOrder():
    FUNCNAME = ogNvramGetOrder.__name__
    # Si se solicita, mostrar ayuda.
    if "help" in args:
        ogHelp(FUNCNAME, FUNCNAME, FUNCNAME)
        return
    
    # Si no es equipo UEFI salir con error
    if not ogIsEfiActive():
        ogRaiseError(OG_ERR_NOTUEFI)
        return

    output = subprocess.check_output(['efibootmgr']).decode().split('\n')
    for line in output:
        if "BootOrder" in line:
            bootorder = line.split(':')[1].strip()
            return bootorder
    return None

def ogNvramGetTimeout():
    FUNCNAME = ogNvramGetTimeout.__name__
    # Si se solicita, mostrar ayuda.
    if "help" in args:
        ogHelp(FUNCNAME, FUNCNAME, FUNCNAME)
        return
    
    # Si no es equipo UEFI salir con error
    if not ogIsEfiActive():
        ogRaiseError(OG_ERR_NOTUEFI)
        return

    output = subprocess.check_output(['efibootmgr']).decode().split('\n')
    for line in output:
        if "Timeout" in line:
            timeout = line.split(':')[1].strip()
            return timeout
    return None

def ogGrubUefiConf(*args):
    FUNCNAME = ogGrubUefiConf.__name__
    EFIDIR = None
    BOOTLABEL = None
    GRUBEFI = None
    UUID = None
    DEVICE = None
    PREFIXSECONDSTAGE = None
    EFIGRUBDIR = None

    # Si se solicita, mostrar ayuda.
    if "help" in args:
        ogHelp(FUNCNAME, f"{FUNCNAME} int_ndisk int_part [ str_dir_grub ]", f"{FUNCNAME} 1 2", f"{FUNCNAME} 1 3 /boot/grubPARTITION")
        return

    # Error si no se reciben al menos 2 parámetros.
    if len(args) < 2:
        ogRaiseError(OG_ERR_FORMAT, f"{FUNCNAME} int_ndisk int_part [ str_dir_grub ]")
        return

    EFIDIR = ogMount(ogGetEsp())
    if EFIDIR is None:
        ogRaiseError(OG_ERR_PARTITION, "ESP")
        return

    BOOTLABEL = f"Part-{int(args[0]):02d}-{int(args[1]):02d}"
    EFIGRUBDIR = f"{EFIDIR}/EFI/{BOOTLABEL}/boot/grub"
    # Comprobamos que existe directorio
    if not os.path.isdir(EFIGRUBDIR):
        os.makedirs(EFIGRUBDIR)

    # Parcheamos uuid y particion en grub.cfg
    UUID = subprocess.check_output(['blkid', '-o', 'value', '-s', 'UUID', ogDiskToDev(args[0], args[1])]).decode().strip()
    DEVICE = f"hd{int(args[0]) - 1},gpt{int(args[1])}"

    with open(f"{EFIGRUBDIR}/grub.cfg", "w") as f:
        f.write(f"set root='{DEVICE}'\n")
        f.write(f"set prefix=($root)'{args[2]}/boot/grub'\n")
        f.write(f"configfile $prefix/grub.cfg\n")

    # Provisional: confirmar si el segundo archivo se utiliza
    shutil.copy(f"{EFIGRUBDIR}/grub.cfg", f"{EFIDIR}/EFI/{BOOTLABEL}/grub.cfg")

def ogNvramInactiveEntry(*args):
    FUNCNAME = ogNvramInactiveEntry.__name__
    NUMENTRY = None

    # Si se solicita, mostrar ayuda.
    if "help" in args:
        ogHelp(FUNCNAME, f"{FUNCNAME} [ Num_order_entry | Label_entry ]", f"{FUNCNAME} 2", f'{FUNCNAME} "Windows Boot Manager"')
        return
    
    # Error si no se recibe 1 parámetro.
    if len(args) != 1:
        ogRaiseError(OG_ERR_FORMAT, f"{FUNCNAME} [ Num_order_entry | Label_entry ]")
        return

    # Si no es equipo UEFI salir con error
    if not ogIsEfiActive():
        ogRaiseError(OG_ERR_NOTUEFI)
        return

    # Distingo si es número de orden o etiqueta
    if args[0].isdigit():
        NUMENTRY = subprocess.check_output(['efibootmgr']).decode().split('\n')
        for entry in NUMENTRY:
            if entry.startswith(args[0]):
                NUMENTRY = entry[4:8]
                break
    else:
        NUMENTRY = subprocess.check_output(['efibootmgr']).decode().split('\n')
        for entry in NUMENTRY:
            if entry.startswith(args[0]):
                NUMENTRY = entry[4:8]
                break

    if NUMENTRY == "":
        ogRaiseError(OG_ERR_NOTFOUND, f"NVRAM entry '{args[0]}'")
        return

    subprocess.run(['efibootmgr', '-A', '-b', NUMENTRY], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

def ogNvramList():
    FUNCNAME = ogNvramList.__name__
    # Si se solicita, mostrar ayuda.
    if "help" in args:
        ogHelp(FUNCNAME, FUNCNAME, FUNCNAME)
        return
    
    # Si no es equipo UEFI salir con error
    if not ogIsEfiActive():
        ogRaiseError(OG_ERR_NOTUEFI)
        return

    output = subprocess.check_output(['efibootmgr']).decode().split('\n')
    for line in output:
        if line.startswith("Boot"):
            num_entry = line[4:8]
            label_entry = line[line.index(num_entry):]
            active = "*" if line.startswith("*") else ""
            print(f"{num_entry} {label_entry} {active}")

def ogNvramPxeFirstEntry():
    FUNCNAME = ogNvramPxeFirstEntry.__name__
    NUMENTRY = None
    ORDER = None

    # Si se solicita, mostrar ayuda.
    if "help" in args:
        ogHelp(FUNCNAME, FUNCNAME, FUNCNAME)
        return
    
    # Si no es equipo UEFI salir con error
    if not ogIsEfiActive():
        ogRaiseError(OG_ERR_NOTUEFI)
        return

    NUMENTRY = subprocess.check_output(['efibootmgr']).decode().split('\n')
    for entry in NUMENTRY:
        if entry.startswith("IPv4"):
            NUMENTRY = entry[4:8]
            break

    # Si la entrada es la primera nos salimos.
    if NUMENTRY in ogNvramGetOrder().split(','):
        return

    # Si la entrada ya existe la borramos.
    ORDER = ogNvramGetOrder().split(',')
    if NUMENTRY in ORDER:
        ORDER.remove(NUMENTRY)

    ogNvramSetOrder(','.join([NUMENTRY] + ORDER))

def ogRestoreEfiBootLoader(*args):
    FUNCNAME = ogRestoreEfiBootLoader.__name__
    MNTDIR = None
    EFIDIR = None
    BOOTLABEL = None
    OSVERSION = None
    LOADER = None
    UUID = None
    DEVICE = None

    # Si se solicita, mostrar ayuda.
    if "help" in args:
        ogHelp(FUNCNAME, f"{FUNCNAME} int_ndisk int_part", f"{FUNCNAME} 1 2")
        return

    # Error si no se reciben 2 parámetros.
    if len(args) != 2:
        ogRaiseError(OG_ERR_FORMAT, f"{FUNCNAME} int_ndisk int_part")
        return

    # Comprobamos que exista partición de sistema y la ESP
    MNTDIR = ogMount(args[0], args[1])
    if MNTDIR is None:
        ogRaiseError(OG_ERR_PARTITION, f"{DISK} {PART}")
        return

    EFIDIR = ogMount(ogGetEsp())
    if EFIDIR is None:
        ogFormat(ogGetEsp(), "FAT32")
        EFIDIR = ogMount(ogGetEsp())
        if EFIDIR is None:
            ogRaiseError(OG_ERR_PARTITION, "ESP")
            return

    # Comprobamos que exista el cargador
    BOOTLABEL = f"Part-{int(args[0]):02d}-{int(args[1]):02d}"
    OSVERSION = ogGetOsVersion(args[0], args[1])
    if "Windows" in OSVERSION:
        LOADER = ogGetPath(f"{MNTDIR}/ogBoot/bootmgfw.efi")
        if LOADER is None:
            ogRaiseError(OG_ERR_NOTOS, f"{args[0]} {args[1]} ({OSVERSION}, EFI)")
            return
        if os.path.isdir(f"{EFIDIR}/EFI/{BOOTLABEL}"):
            shutil.rmtree(f"{EFIDIR}/EFI/{BOOTLABEL}")
        os.makedirs(f"{EFIDIR}/EFI/{BOOTLABEL}")
        shutil.copytree(f"{LOADER.rstrip('/bootmgfw.efi')}", f"{EFIDIR}/EFI/{BOOTLABEL}/Boot")
        shutil.copy(LOADER, f"{EFIDIR}/EFI/{BOOTLABEL}/Boot/ogloader.efi")
        if os.path.isdir(f"{EFIDIR}/EFI/Microsoft"):
            os.rename(f"{EFIDIR}/EFI/Microsoft", f"{EFIDIR}/EFI/Microsoft.backup.og")

def ogRestoreUuidPartitions():
    FUNCNAME = ogRestoreUuidPartitions.__name__
    DISK = None
    PART = None
    IMGNAME = None
    INFOFILE = None
    DEVICE = None
    DATA = None
    GUID = None
    UUID = None
    IMGGUID = None
    EFIDEVICE = None
    EFIDATA = None
    EFIGUID = None
    EFIUUID = None
    IMGEFIGUID = None

    # Si se solicita, mostrar ayuda.
    if "help" in args:
        ogHelp(FUNCNAME, f"{FUNCNAME} REPO|CACHE str_imgname int_ndisk int_npart", f"{FUNCNAME} REPO Windows 1 2")
        return

    # Error si no se reciben 4 parámetros.
    if len(args) != 4:
        ogRaiseError(OG_ERR_FORMAT, f"{FUNCNAME} REPO|CACHE str_imgname int_ndisk int_npart")
        return

    # Sólo se ejecuta si es UEFI
    if not ogIsEfiActive():
        return

    # Parámetros de entrada
    IMGNAME = args[1]
    INFOFILE = f"{OGIMG}/.{IMGNAME}.img.json"
    if args[0].upper() == "CACHE":
        INFOFILE = f"{OGCAC}{INFOFILE}"
    # TODO: que la función getPath soporte archivos ocultos
    if not os.path.exists(INFOFILE):
        ogRaiseError(OG_ERR_NOTFOUND, INFOFILE)
        return

    DISK = args[2]
    PART = args[3]

    DEVICE = ogDiskToDev(DISK)
    EFIDISK, EFIPART = ogGetEsp().split()

    # Datos de la imagen
    IMGGUID = subprocess.check_output(['jq', '.guid', INFOFILE]).decode().strip().strip('"')
    IMGEFIGUID = subprocess.check_output(['jq', '.espguid', INFOFILE]).decode().strip().strip('"')

    # Datos actuales
    DATA = subprocess.check_output(['sfdisk', '-J', DEVICE]).decode()
    GUID = subprocess.check_output(['echo', DATA, '|', 'jq', '".partitiontable|.id"', '|', 'tr', '-d', '"']).decode().strip()

    if IMGGUID != GUID:
        subprocess.run(['sgdisk', '-U', IMGGUID, DEVICE])
        subprocess.run(['partprobe'])

    if DISK == EFIDISK:
        EFIDATA = DATA
        EFIDEVICE = DEVICE
    else:
        EFIDEVICE = ogDiskToDev(EFIDISK)
        EFIDATA = subprocess.check_output(['sfdisk', '-J', EFIDEVICE]).decode()
        EFIGUID = subprocess.check_output(['echo', EFIDATA, '|', 'jq', '".partitiontable|.id"', '|', 'tr', '-d', '"']).decode().strip()

        if IMGEFIGUID != EFIGUID:
            subprocess.run(['sgdisk', '-U', IMGEFIGUID, EFIDEVICE])
            subprocess.run(['partprobe'])

def ogNvramSetNext(*args):
    FUNCNAME = ogNvramSetNext.__name__
    NUMENTRY = None

    # Si se solicita, mostrar ayuda.
    if "help" in args:
        ogHelp(FUNCNAME, f"{FUNCNAME} [ Num_order_entry | Label_entry ]", f"{FUNCNAME} 2", f'{FUNCNAME} "Windows Boot Manager"')
        return
    
    # Error si no se recibe 1 parámetro.
    if len(args) != 1:
        ogRaiseError(OG_ERR_FORMAT, f"{FUNCNAME} [ Num_order_entry | Label_entry ]")
        return

    # Si no es equipo UEFI salir con error
    if not ogIsEfiActive():
        ogRaiseError(OG_ERR_NOTUEFI)
        return

    # Distingo si es número de orden o etiqueta
    if args[0].isdigit():
        NUMENTRY = subprocess.check_output(['efibootmgr']).decode().split('\n')
        for entry in NUMENTRY:
            if entry.startswith(args[0]):
                NUMENTRY = entry[4:8]
                break
    else:
        NUMENTRY = subprocess.check_output(['efibootmgr']).decode().split('\n')
        for entry in NUMENTRY:
            if entry.startswith(args[0]):
                NUMENTRY = entry[4:8]
                break

    if NUMENTRY == "":
        ogRaiseError(OG_ERR_NOTFOUND, f"NVRAM entry '{args[0]}'")
        return

    subprocess.run(['efibootmgr', '-n', NUMENTRY], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

def ogNvramSetOrder(*args):
    FUNCNAME = ogNvramSetOrder.__name
    # Si se solicita, mostrar ayuda.
    if "help" in args:
        ogHelp(FUNCNAME, f"{FUNCNAME} Num_order1 [ Num_order2 ] ...", f"{FUNCNAME} 1 3")
        return
    
    # Error si no se recibe al menos 1 parámetro.
    if len(args) < 1:
        ogRaiseError(OG_ERR_FORMAT, f"{FUNCNAME} Num_order1 [ Num_order2 ] ...")
        return

    # Si no es equipo UEFI salir con error
    if not ogIsEfiActive():
        ogRaiseError(OG_ERR_NOTUEFI)
        return

    # Comprobamos que sean números
    for arg in args:
        if not arg.isdigit():
            ogRaiseError(OG_ERR_FORMAT, f"{FUNCNAME} Num_order1 [ Num_order2 ] ...")
            return

    # Entradas de la NVRAM actuales
    NUMENTRYS = subprocess.check_output(['efibootmgr']).decode().split('\n')
    NUMENTRYS = [entry[4:8] for entry in NUMENTRYS if entry.startswith("Boot")]

    ORDER = ""
    for arg in args:
        # Si no existe la entrada me salgo
        if arg not in NUMENTRYS:
            ogRaiseError(OG_ERR_NOTFOUND, f"NVRAM entry order '{arg}'")
            return
        ORDER += f",{arg}"

    # Cambiamos el orden
    subprocess.run(['efibootmgr', '-o', ORDER[1:]], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

def ogNvramSetTimeout(*args):
    FUNCNAME = ogNvramSetTimeout.__name__

    # Si se solicita, mostrar ayuda.
    if "help" in args:
        ogHelp(FUNCNAME, f"{FUNCNAME} int_Timeout (seg)", f"{FUNCNAME} 2")
        return

    # Si no es equipo UEFI salir con error
    if not ogIsEfiActive():
        ogRaiseError(OG_ERR_NOTUEFI)
        return

    # Error si no se recibe 1 parámetro.
    if len(args) != 1:
        ogRaiseError(OG_ERR_FORMAT, f"{FUNCNAME} int_Timeout (seg)")
        return

    # Comprobamos que sea un número
    if not args[0].isdigit():
        ogRaiseError(OG_ERR_FORMAT, f"{FUNCNAME} int_Timeout (seg)")
        return

    # Cambiamos el timeout
    subprocess.run(['efibootmgr', '-t', args[0]], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

def ogUuidChange(*args):
    FUNCNAME = ogUuidChange.__name__
    MNTDIR = None
    DEVICE = None
    UUID = None
    NEWUUID = None

    # Si se solicita, mostrar ayuda.
    if "help" in args:
        ogHelp(FUNCNAME, f"{FUNCNAME} int_ndisk int_part", f"{FUNCNAME} 1 2")
        return

    # Error si no se reciben al menos 2 parámetros.
    if len(args) < 2:
        ogRaiseError(OG_ERR_FORMAT, f"{FUNCNAME} int_ndisk int_part")
        return

    # Comprobamos que exista la partición
    MNTDIR = ogMount(args[0], args[1])
    if MNTDIR is None:
        ogRaiseError(OG_ERR_NOTFOUND, f"Device {args[0]} {args[1]}")
        return

    DEVICE = ogDiskToDev(args[0], args[1])
    UUID = subprocess.check_output(['blkid', '-o', 'value', '-s', 'UUID', DEVICE]).decode().strip()
    NEWUUID = subprocess.check_output(['cat', '/proc/sys/kernel/random/uuid']).decode().strip()

    # Cambiamos UUID a la partición
    ogUnmount(args[0], args[1])
    subprocess.run(['tune2fs', DEVICE, '-U', NEWUUID], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

    # Cambiamos UUID en la configuración (fstab y grub)
    ogMount(args[0], args[1])
    for f in [f"{MNTDIR}/etc/fstab", f"{MNTDIR}/{{,boot/}}{{grubMBR,grubPARTITION}}/boot/{{,grub{,2},{,efi/}EFI/*/}}/{{menu.lst,grub.cfg}}"]:
        if os.path.isfile(f):
            subprocess.run(['sed', '-i', f's/{UUID}/{NEWUUID}/g', f], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)