from engine.SystemLib import *

def ogLoadHiveWindows():
    FUNCNAME = ogLoadHiveWindows.__name__
    # Variables locales.
    PART = None
    DISK = None

    # Si se solicita, mostrar ayuda.
    if len(sys.argv) > 1 and sys.argv[1] == "help":
        ogHelp(FUNCNAME, f"{FUNCNAME} int_ndisk int_partition", f"{FUNCNAME} 1 1")
        return

    # Error si no se reciben 2 parámetros.
    if len(sys.argv) != 3:
        return ogRaiseError(OG_ERR_FORMAT)

    DISK = int(sys.argv[1])
    PART = int(sys.argv[2])

    # Comprobaciones redundantes: borrar"
    # ogDiskToDev(DISK, PART) or return ogRaiseError(OG_ERR_PARTITION, "particion de windows no detectada")
    # ogGetOsType(DISK, PART).startswith("Windows") or return ogRaiseError(OG_ERR_NOTOS, "no es windows")
    # VERSION = ogGetOsVersion(DISK, PART)
    # Fin Comprobaciones redundantes: borrar"

    # primera fase, carga de los hive del sistema
    if ogGetPath(DISK, PART, "WINDOWS"):
        SYSTEMROOT = "Windows"
    elif ogGetPath(DISK, PART, "WINNT"):
        SYSTEMROOT = "winnt"
    else:
        return ogRaiseError(OG_ERR_NOTOS, "version windows no detectada")

    hiveSAM = ogGetPath(DISK, PART, f"/{SYSTEMROOT}/system32/config/SAM")
    if hiveSAM:
        os.environ["hiveSAM"] = hiveSAM
    else:
        return ogRaiseError(OG_ERR_NOTOS, "hive SAM no detectada")

    hiveSYSTEM = ogGetPath(DISK, PART, f"/{SYSTEMROOT}/system32/config/system")
    if hiveSYSTEM:
        os.environ["hiveSYSTEM"] = hiveSYSTEM
    else:
        return ogRaiseError(OG_ERR_NOTOS, "hive SYSTEM no detectada")

    hiveSOFTWARE = ogGetPath(DISK, PART, f"/{SYSTEMROOT}/system32/config/software")
    if hiveSOFTWARE:
        os.environ["hiveSOFTWARE"] = hiveSOFTWARE
    else:
        return ogRaiseError(OG_ERR_NOTOS, "hive SOFTWARE no detectada")

    os.environ["TEMPhive"] = "/tmp/tmpregistry"

    # segunda fase, carga de los hive de usuarios windows.
    COUNT = 3
    # TODO WINDOWS XP WINDOWS7
    BASEHOMEDIR = ogGetPath(DISK, PART, "/Documents and Settings")
    TMPUSERFILE = "/tmp/WuserRegAndDAT.tmp"
    with open(TMPUSERFILE, "w") as f:
        f.write("\n".join(glob.glob(f"{BASEHOMEDIR}/**/NTUSER.DAT", recursive=True)))

    LISTUSERS = subprocess.check_output(["drbl-chntpw", "-l", hiveSAM]).decode().splitlines()
    LISTUSERS = [user.split("<")[1].split(">")[0] for user in LISTUSERS if "RID" in user]

    for user in LISTUSERS:
        # Comprobamos que el usuario registrado tiene .DAT
        if HOMEDIR := next((line for line in open(TMPUSERFILE) if user in line), None):
            os.environ[user] = f"hiveUSER{COUNT}"
            os.environ[f"hiveUSER{COUNT}"] = HOMEDIR.strip()
            COUNT += 1

    COUNT = 0

def ogUpdateHiveWindows():
    FUNCNAME = ogUpdateHiveWindows.__name__
    # Variables locales.
    PART = None
    DISK = None
    FILE = None

    # TODO detectar llamada a ogLoadHiveWindows

    # Si se solicita, mostrar ayuda.
    if len(sys.argv) > 1 and sys.argv[1] == "help":
        ogHelp(FUNCNAME, f"{FUNCNAME} ", f"{FUNCNAME}  ")
        return

    subprocess.call(["drbl-chntpw", "-f", os.environ["TEMPhive"], os.environ["hiveSAM"], os.environ["hiveSYSTEM"], os.environ["hiveSOFTWARE"], os.environ["hiveUSER3"], os.environ["hiveUSER4"], os.environ["hiveUSER5"], os.environ["hiveUSER6"], os.environ["hiveUSER7"], os.environ["hiveUSER8"], os.environ["hiveUSER9"]])

    os.remove(os.environ["TEMPhive"])

    del os.environ["hiveSAM"]
    del os.environ["hiveSYSTEM"]
    del os.environ["hiveSOFTWARE"]
    del os.environ["TEMPhive"]
    del os.environ["hiveUSER3"]
    del os.environ["hiveUSER4"]
    del os.environ["hiveUSER5"]
    del os.environ["hiveUSER6"]
    del os.environ["hiveUSER7"]
    del os.environ["hiveUSER8"]
    del os.environ["hiveUSER9"]

def ogHiveNTRunMachine():
    FUNCNAME = ogHiveNTRunMachine.__name__
    # Variables locales.
    PART = None
    DISK = None
    FILE = None

    # Si se solicita, mostrar ayuda.
    if len(sys.argv) > 1 and sys.argv[1] == "help":
        ogHelp(FUNCNAME, f"{FUNCNAME} PathScripts|command keyName",
                f"{FUNCNAME} c:\\\\Windows\\\\crearusuarios.cmd scripts_crearUsuarios",
                f"{FUNCNAME} \"cmd /c del c:\ogboot.*\" ogcleanboot",
                f"{FUNCNAME} Requiere la previa ejecución de ogLoadHive int_disk int_part",
                f"{FUNCNAME} Despues requiere el ogUpdateHive")
        return

    # Error si no se reciben al menos 1 parámetros.
    if len(sys.argv) != 3:
        return ogRaiseError(OG_ERR_FORMAT)

    with open(os.environ["TEMPhive"], "a") as f:
        f.write(f"h 2\ncd \\Microsoft\\Windows\\CurrentVersion\\Run\nnv 1 {sys.argv[2]}\ned {sys.argv[2]}\n{sys.argv[1]}\n")

def ogNTPolUserOn():
    FUNCNAME = ogNTPolUserOn.__name__
    # Variables locales.
    PART = None
    DISK = None
    FILE = None

    # Si se solicita, mostrar ayuda.
    if len(sys.argv) > 1 and sys.argv[1] == "help":
        ogHelp(FUNCNAME, f"{FUNCNAME} id_hive_user", f"{FUNCNAME} NombreUsuario", f"{FUNCNAME}")
        return

    # TODO: error si no se ha llamado previamente a ogLoadHiveWindows
    if "hiveSAM" not in os.environ:
        return ogRaiseError(OG_ERR_FORMAT, "se debe utilizar primero la utilidad ogLoadHiveWindows")

    # TODO: error si el usuario no tiene cuenta en windows.
    if subprocess.call(["drbl-chntpw", "-l", os.environ["hiveSAM"]], stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.decode().count(f"RID: {sys.argv[1]}") == 0:
        return ogRaiseError(OG_ERR_FORMAT, f"el usuario {sys.argv[1]} no tiene cuenta en este windows: Compruebe mayusculas o minusculas")

    # TODO: error si no el usario no no tiene HIVE asociado.
    if sys.argv[1] not in os.environ:
        return ogRaiseError(OG_ERR_FORMAT, "el usuario no tiene hive creado")

    HIVEID = os.environ[sys.argv[1]].replace("hiveUSER", "")

    # echo "IMPORTANTE:  la variable HiveUser3=/mnt/windows/Document/\ and/\ Seeting\alumnmos\NTUSER.dat"
    print(HIVEID)
    # cp /var/EAC/admin/utilswin/Fondo.BMP ${particion}/WINDOWS/

    with open(os.environ["TEMPhive"], "a") as f:
        f.write(f"h {HIVEID}\n")
        f.write("cd \\Control Panel\\Desktop\n")
        f.write("ed Wallpaper\n")
        f.write("C:\\WINDOWS\\fondo.bmp\n")
        f.write("\n")
        f.write("cd \\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\n")
        f.write("nk Explorer\n")
        f.write("cd Explorer\n")
        f.write("\n")
        f.write("nv 4 NoDesktop\n")
        f.write("ed NoDesktop\n")
        f.write("1\n")
        f.write("\n")
        f.write("nv 4 NoSimpleStartMenu\n")
        f.write("ed NoSimpleStartMenu\n")
        f.write("1\n")
        f.write("nv 4 NoWindowsUpdate\n")
        f.write("ed NoWindowsUpdate\n")
        f.write("1\n")
        f.write("\n")
        f.write("nv 4 NoSMConfigurePrograms\n")
        f.write("ed NoSMConfigurePrograms\n")
        f.write("1\n")
        f.write("\n")
        f.write("nv 4 NoChangeStartMenu\n")
        f.write("ed NoChangeStartMenu\n")
        f.write("1\n")
        f.write("\n")
        f.write("nv 4 Intellimenus\n")
        f.write("ed Intellimenus\n")
        f.write("1\n")
        f.write("\n")
        f.write("nv 4 NoRun\n")
        f.write("ed NoRun\n")
        f.write("1\n")
        f.write("\n")
        f.write("nv 4 NoRecentDocsHistory\n")
        f.write("ed NoRecentDocsHistory\n")
        f.write("1\n")

def NTChangeName():
    if len(sys.argv) == 1:
        print("sintaxis: NTChangeName str_$var")
        print("ejemplos: NTChangeName adi${IPcuatro}-xp")
        return

    with open(os.environ["TEMPhive"], "a") as f:
        f.write("h 1\n")
        f.write("ed ControlSet001\\Control\\ComputerName\\ComputerName\\ComputerName\n")
        f.write(sys.argv[1] + "\n")
        f.write("ed ControlSet001\\Services\\Tcpip\\Parameters\\Hostname\n")
        f.write(sys.argv[1] + "\n")
        f.write("ed ControlSet001\\Services\\Tcpip\\Parameters\\NV Hostname\n")
        f.write(sys.argv[1] + "\n")
        f.write("h 2\n")
        f.write("cd \\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\n")
        f.write("ed DefaultDomainName\n")
        f.write(sys.argv[1] + "\n")

def NTSetGroupName(group_name):
    if len(sys.argv) == 1:
        print("sintaxis: NTSetGroupName str_$var")
        print("ejemplos: NTSetGroupName adi")
        return

    with open(os.environ["TEMPhive"], "a") as f:
        f.write("h 2\n")
        f.write("ed \\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\DefaultDomainName\n")
        f.write(group_name + "\n")

def NTSetOwner(owner, organization):
    if len(sys.argv) == 1:
        print("sintaxis: NtSetOwner str_propietario str_organizacion")
        print("ejemplos: NTSetOwner eu\\ politecnica universidad\\ de\\ malaga")
        return

    with open(os.environ["TEMPhive"], "a") as f:
        f.write("h 2\n")
        f.write("ed \\Microsoft\\Windows NT\\CurrentVersion\\RegisteredOwner\n")
        f.write(owner + "\n")
        f.write("ed \\Microsoft\\Windows NT\\CurrentVersion\\RegisteredOrganization\n")
        f.write(organization + "\n")

def NTAutoLogon():
    if len(sys.argv) == 1:
        print("sintaxis: NTAutoLogon int_Activar int_nves str_usuario str_passwd str_equipo")
        print("ejemplos: NTAutoLogon 1 2 administrador 3451 $equipo")
        print("IMPORTANTE: cuando AutoLogonCount llegue a 0, activa el AutoAdminLogon a 0. Pero no borra los valores de DefaultPassword")
        return 2

    with open(os.environ["TEMPhive"], "a") as f:
        f.write("hive 2\n")
        f.write("cd \\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\n")
        f.write(f"nv 1 AutoAdminLogon\n")
        f.write(f"ed AutoAdminLogon\n")
        f.write(f"{sys.argv[1]}\n")
        f.write(f"nv 1 AutoLogonCount\n")
        f.write(f"ed AutoLogonCount\n")
        f.write(f"{sys.argv[2]}\n")
        f.write(f"nv 1 DefaultUserName\n")
        f.write(f"ed DefaultUserName\n")
        f.write(f"{sys.argv[3]}\n")
        f.write(f"nv 1 DefaultDomainName\n")
        f.write(f"ed DefaultDomainName\n")
        f.write(f"{sys.argv[5]}\n")

        if sys.argv[4] == "none":
            f.write("dv DefaultPassword\n")
        else:
            f.write(f"nv 1 DefaultPassword\n")
            f.write(f"ed DefaultPassword\n")
            f.write(f"{sys.argv[4]}\n")

def NTStatusRatonTeclado():
    if len(sys.argv) == 1:
        print("sintaxis: NTStatusRatonTeclado int_StatusRaton int_StatusTeclado")
        print("ejemplos: NTStatusRatonTeclado 1 4")
        return 2

    with open(os.environ["TEMPhive"], "a") as f:
        f.write("hive 1\n")
        f.write("cd \\ControlSet001\\Services\\Mouclass\n")
        f.write("ed Start\n")
        f.write(sys.argv[1] + "\n")
        f.write("cd \\ControlSet001\\Services\\Kbdclass\n")
        f.write("ed Start\n")
        f.write(sys.argv[2] + "\n")

def NTRunOnceMachine():
    if len(sys.argv) == 1:
        print("sintaxis: NTRunOnceMachine PathScripts idScripts")
        print("ejemplo: NTRunOnceMachine c:\\\\WINDOWS\\\\crearusuarios.bat scripts1")
        print("IMPORTANTE: el path debe llevar dos barras \\, pero como se deben 'escapar' debes poner cuatro \\\\")
        return 2

    with open(os.environ["TEMPhive"], "a") as f:
        f.write("h 2\n")
        f.write("cd \\Microsoft\\Windows\\CurrentVersion\\RunOnce\n")
        f.write(f"nv 1 {sys.argv[2]}\n")
        f.write(f"ed {sys.argv[2]}\n")
        f.write(f"{sys.argv[1]}\n")

def NTRunMachine():
    if len(sys.argv) == 1:
        print("sintaxis: NTRunMachine PathScripts idScripts")
        print("ejemplo: NTRunMachine c:\\\\WINDOWS\\\\crearusuarios.bat scripts1")
        print("IMPORTANTE: el path debe llevar dos barras \\, pero como se deben 'escapar' debes poner cuatro \\\\")
        return 2

    with open(os.environ["TEMPhive"], "a") as f:
        f.write("h 2\n")
        f.write("cd \\Microsoft\\Windows\\CurrentVersion\\Run\n")
        f.write(f"nv 1 {sys.argv[2]}\n")
        f.write(f"ed {sys.argv[2]}\n")
        f.write(f"{sys.argv[1]}\n")

def NTRunUser():
    if len(sys.argv) == 1:
        print("sintaxis: str_PathWINScripts str_idScripts Int_hive||$usuario")
        print("ejemplo: c:\\\\WINDOWS\\\\crearusuarios.bat scripts1 3")
        print("IMPORTANTE: el pathWIN debe llevar dos barras \\, pero como se deben 'escapar' debes poner cuatro \\\\")
        print("IMPORTANTE: el pathLinux si lleva espacios debe escaparse con una barra \\")
        print("IMPORTANTE Int_hive: 3 para el primer usuario, 4 para el segundo usuario")
        print("requiere export un HiveUser3=/mnt/windows/Document\\ and\\ Seeting\\alumnmos\\NTUSER.dat")
        return 2

    with open(os.environ["TEMPhive"], "a") as f:
        f.write(f"h {sys.argv[3]}\n")
        f.write("cd \\Software\\Microsoft\\Windows\\CurrentVersion\\Run\n")
        f.write(f"nv 1 {sys.argv[2]}\n")
        f.write(f"ed {sys.argv[2]}\n")
        f.write(f"{sys.argv[1]}\n")

def NTPolUserOn():
    if len(sys.argv) == 1:
        print("sintaxis: NTPolUserOn Int_hive")
        print("ejemplo: NTPolUserOn 3")
        print("IMPORTANTE: la variable HiveUser3=/mnt/windows/Document/ and/ Seeting/alumnmos/NTUSER.dat")
        return 2

    with open(os.environ["TEMPhive"], "a") as f:
        f.write(f"h {sys.argv[1]}\n")
        f.write("cd \\Control Panel\\Desktop\n")
        f.write("ed Wallpaper\n")
        f.write("C:\\WINDOWS\\fondo.bmp\n")
        f.write("\n")
        f.write("cd \\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\n")
        f.write("nk Explorer\n")
        f.write("cd Explorer\n")
        f.write("\n")
        f.write("nv 4 NoDesktop\n")
        f.write("ed NoDesktop\n")
        f.write("1\n")
        f.write("\n")
        f.write("nv 4 NoSimpleStartMenu\n")
        f.write("ed NoSimpleStartMenu\n")
        f.write("1\n")
        f.write("nv 4 NoWindowsUpdate\n")
        f.write("ed NoWindowsUpdate\n")
        f.write("1\n")
        f.write("\n")
        f.write("nv 4 NoSMConfigurePrograms\n")
        f.write("ed NoSMConfigurePrograms\n")
        f.write("1\n")
        f.write("\n")
        f.write("nv 4 NoChangeStartMenu\n")
        f.write("ed NoChangeStartMenu\n")
        f.write("1\n")
        f.write("\n")
        f.write("nv 4 Intellimenus\n")
        f.write("ed Intellimenus\n")
        f.write("1\n")
        f.write("\n")
        f.write("nv 4 NoRun\n")
        f.write("ed NoRun\n")
        f.write("1\n")
        f.write("\n")
        f.write("nv 4 NoRecentDocsHistory\n")
        f.write("ed NoRecentDocsHistory\n")
        f.write("1\n")

def NTPolUserOFF(hive):
    if len(sys.argv) == 1:
        print("sintaxis: NTPolUserOFF Int_hive")
        print("ejemplo: NTPolUserOFF 3")
        print("IMPORTANTE: la variable HiveUser3=/mnt/windows/Document/ and/ Seeting/alumnmos/NTUSER.dat")
        return 2

    with open(os.environ["TEMPhive"], "a") as f:
        f.write(f"h {hive}\n")
        f.write("cd \\Control Panel\\Desktop\n")
        f.write("ed Wallpaper\n")
        f.write("C:\\WINDOWS\\web\\wallpaper\\Felicidad.bmp\n")
        f.write("\n")
        f.write("cd \\Software\\Microsoft\\Windows\\CurrentVersion\\\n")
        f.write("rdel Policies\n")
        f.write("nk Policies\n")
        f.write("1\n")

def ogSetWindowsChkdisk():
    if len(sys.argv) == 1:
        print("sintaxis: true|TRUE|0 false|false|1")
        print("ejemplos: int=0 desactivado int=1 activado")
        return 2

    valor = ""
    if sys.argv[1] in ["0", "true", "TRUE"]:
        valor = "autocheck autochk *"
    elif sys.argv[1] in ["1", "false", "FALSE"]:
        valor = "none"
    else:
        return 0

    with open(os.environ["TEMPhive"], "a") as f:
        f.write("hive 1\n")
        f.write("cd \\ControlSet001\\Control\\Session Manager\n")
        f.write("ed BootExecute\n")
        f.write(valor + "\n")
        f.write("--n\n")

def NTStartRecovery():
    if len(sys.argv) == 1:
        print("sintaxis: Int-Status")
        print("ejemplos: int=0 desactivado int=1 activado")
        return 2

    valor = ""
    if sys.argv[1] == "0":
        valor = "none"
    elif sys.argv[1] == "1":
        valor = "00000000"
    else:
        return 0

    with open(os.environ["TEMPhive"], "a") as f:
        f.write("hive 2\n")
        f.write("#cd \\Policies\\Microsoft\\Windows\\WinRE\n")
        f.write("#ed DisableSetup\n")
        f.write("cd \\Policies\\Microsoft\\Windows\n")
        f.write("nk WinRE\n")
        f.write("nv 4 DisableSetup\n")
        f.write("ed DisableSetup\n")
        f.write(valor + "\n")
        f.write("--n\n")

def ogSchrootLinux():
    FUNCNAME = ogSchrootLinux.__name
    # Variables locales.
    PART = None
    DISK = None
    DIRCONF = "/etc/schroot"

    # Si se solicita, mostrar ayuda.
    if len(sys.argv) > 1 and sys.argv[1] == "help":
        ogHelp(FUNCNAME, f"{FUNCNAME} int_ndisk int_partition", f"{FUNCNAME} 1 1")
        return

    # Error si no se reciben 2 parámetros.
    if len(sys.argv) != 3:
        return ogRaiseError(OG_ERR_FORMAT)

    DISK = int(sys.argv[1])
    PART = int(sys.argv[2])

    VERSION = ogGetOsVersion(DISK, PART)
    if "Linux" not in VERSION:
        return ogRaiseError(OG_ERR_NOTOS, "no es linux")

    ogUnmount(DISK, PART) or return ogRaiseError(OG_ERR_NOTOS, "no es linux")

    SCHROOTDEVICE = ogDiskToDev(DISK, PART)

    os.remove(f"{DIRCONF}/mount-defaults")
    os.remove(f"{DIRCONF}/schroot.conf")

    with open(f"{DIRCONF}/mount-defaults", "w") as f:
        f.write("# <file system> <mount point>   <type>  <options>       <dump>  <pass>\n")
        f.write("proc            /proc           proc    defaults        0       0\n")
        f.write("/dev            /dev            none    rw,bind         0       0\n")
        f.write("/dev/pts        /dev/pts        none    rw,bind         0       0\n")
        f.write("/dev/shm        /dev/shm        none    rw,bind         0       0\n")

    with open(f"{DIRCONF}/schroot.conf", "w") as f:
        f.write("[linux]\n")
        f.write(f"description={VERSION}\n")
        f.write("type=block-device\n")
        f.write(f"device={SCHROOTDEVICE}\n")

    subprocess.call(["schroot", "-c", "linux"])
    subprocess.call(["schroot", "-end-sessiona", "--all-sessions"])

def ogDiskToRelativeDev(int_disk, int_partition=None):
    FUNCNAME = ogDiskToRelativeDev.__name__
    if int_partition is None:
        # Sintaxis1: IdPartition int_disk
        # Ejemplo1: IdPartition 1 -> sda
        return ogDiskToDev(int_disk)
    else:
        # Sintaxis2: IdPartition int_disk int_partition
        # Ejemplo2: IdPartition 1 2 -> sda2
        return ogDiskToDev(int_disk) + str(int_partition)
    
def ogDeletePartitionsLabels():
    FUNCNAME = ogDeletePartitionsLabels.__name__
    # Si se solicita, mostrar ayuda.
    if len(sys.argv) > 1 and sys.argv[1] == "help":
        ogHelp(FUNCNAME, f"{FUNCNAME}", f"{FUNCNAME}")
        return

    subprocess.call(["rm", "/dev/disk/by-label/*"])

def ogInfoCache():
    info = subprocess.check_output(["df", "-h"]).decode()
    info = info.split("\n")
    for line in info:
        if "$OGCAC" in line:
            infoFilesystem = line.split()[0]
            infoSize = line.split()[1]
            infoUsed = line.split()[2]
            infoAvail = line.split()[3]
            infoUsedPorcet = line.split()[4]
            infoMountedOn = line.split()[5]
            break
    else:
        return

    if os.path.exists(f"{OGCAC}{OGIMG}"):
        os.chdir(f"{OGCAC}{OPENGNSYS}")
        content = subprocess.check_output(["find", "images/", "-type", "f"]).decode()
        os.chdir("/")
        print(info)
        print(content)
        print(" ")
    else:
        print(info)