#!/usr/bin/python3

#/**
#         configureOs
#@brief   Script para realizar la configuracion del sistema operativo restaurado.
#@param 1 disco 
#@param 2 particion 
#@return  
#@TODO  comprobar que el tipo de particion corresponde con el sistema de archivos.
#@exception OG_ERR_FORMAT     # 1 formato incorrecto.
#*/ ##

import sys
import os
import os.path
import subprocess

import ogGlobals
import SystemLib
import DiskLib
import FileSystemLib
import NetLib
import InventoryLib
import BootLib
import UEFILib
import PostConfLib
import FileLib

## el código bash original hace:
## [ -f $DEVICECFG ] && source $DEVICECFG
## pero luego no utiliza ninguna de las variables definidas en el archivo...

disk = sys.argv[1]
par  = sys.argv[2]

# Si el sistema de archivos no esta extendido, ampliarlo al tamaño de su partición.
partsize = DiskLib.ogGetPartitionSize (disk, par)
if not partsize: sys.exit (1)
fssize = FileSystemLib.ogGetFsSize (disk, par)
if fssize < partsize:
    print ('Extender sistema de archivos.')
    FileSystemLib.ogExtendFs (disk, par)

# Si no existe partición activa, activar este sistema.
flagactive = DiskLib.ogGetPartitionActive (disk)
if not flagactive: DiskLib.ogSetPartitionActive (disk, par)

# Si el sistema de archivos es de solo lectura, no hacer la post-configuración.
mntdir = FileSystemLib.ogMount (disk, par)
if not FileSystemLib.ogIsWritable (disk, par):
    print ('AVISO: sistema de archivos de solo lectura, no se ejecuta postconfiguración.')
    sys.exit (0)

# Nombre del cliente.
host = NetLib.ogGetHostname()

# Post-configuración personalizada para cada tipo de sistema operativo.
ostype = InventoryLib.ogGetOsType (disk, par)
if 'Windows' == ostype:
    if not host: host = 'pc'
    BootLib.ogSetWindowsName (disk, par, host)                      # Cambiar nombre en sistemas Windows.
    if InventoryLib.ogIsEfiActive():                                # Si es UEFI copio el cargador de arranque a la partición EFI e instalo Grub.
        UEFILib.ogRestoreEfiBootLoader (disk, par)
        esp = DiskLib.ogGetEsp()
        if not esp:
            SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, 'ESP')
            sys.exit (1)
        efidisk, efipart = esp.split()
        BootLib.ogGrubInstallMbr (efidisk, efipart, 'TRUE')
    else:
        BootLib.ogFixBootSector (disk, par)                         # Configurar el boot sector de la partición Windows.
    BootLib.ogWindowsBootParameters (disk, par)                     # Configurar el gestor de arranque de Windows XP/Vista/7.
    BootLib.ogWindowsRegisterPartition (disk, par, 'C', disk, par)  # Registrar en Windows que la partición indicada es su nueva unidad C:\
    PostConfLib.ogConfigureOgagent (disk, par)                      # Configurar nuevo agente OGAgent.
    path1 = FileLib.ogGetPath (file=f'{mntdir}/windows/ogAdmWinClient.exe')
    path2 = FileLib.ogGetPath (file=f'{mntdir}/winnt/ogAdmWinClient.exe')
    if path1 or path2:                                              # Eliminar el antiguo cliente de Windows.
        PostConfLib.ogInstallMiniSetup (disk, par, 'postconf.cmd')
        PostConfLib.ogUninstallWindowsClient (disk, par, 'postconf.cmd')

elif 'Linux' == ostype:
    BootLib.ogConfigureFstab (disk, par)                  # Configuro fstab: particion de Swap y si es UEFI además la partición EFI.
    if InventoryLib.ogIsEfiActive():                      # Si es UEFI instalo Grub en la partición EFI
        esp = DiskLib.ogGetEsp()
        efidisk, efipart = esp.split()
        BootLib.ogGrubInstallMbr (efidisk, efipart, 'TRUE')
    BootLib.ogGrubInstallPartition (disk, par)            ## Instala (no configura) el codigo de arranque del Grub en la partición (no lo configura, se mantiene el original de la imagen)
    find_out = subprocess.run (['find', f'{mntdir}/usr/sbin', f'{mntdir}/sbin', f'{mntdir}/usr/local/sbin', '-name', 'ogAdmLnxClient', '-print'], capture_output=True, text=True).stdout
    if find_out:
        PostConfLib.ogUninstallLinuxClient (disk, par)    # Eliminar el antiguo cliente de Linux.
    PostConfLib.ogConfigureOgagent (disk, par)            # Configurar nuevo agente OGAgent.
    ## Modificar el nombre del equipo
    print (f'Asignar nombre Linux "{host}".')
    etc = FileLib.ogGetPath (src=f'{disk} {par}', file='/etc')
    if os.path.isdir (etc):
        with open (f'{etc}/hostname', 'w') as fd:
            fd.write (f'{host}\n')

elif 'MacOS' == ostype:
    open (f'{mntdir}/osxpostconf', 'a').close()      ## touch, Fichero indicador de activación de postconfiguración.

    # Crear fichero de configuración del servicio de arranque.
    with open (f'{mntdir}/Library/LaunchDaemons/es.opengnsys.postconfd.plist', 'w') as fd:
        fd.write ('<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n')
        fd.write ('<plist version="1.0">\n')
        fd.write ('\t<dict>\n')
        fd.write ('\t\t<key>Label</key>\n')
        fd.write ('\t\t<string>es.opengnsys.postconfd.sh</string>\n')
        fd.write ('\t\t<key>ProgramArguments</key>\n')
        fd.write ('\t\t<array>\n')
        fd.write ('\t\t\t<string>/var/root/postconfd.sh</string>\n')
        fd.write ('\t\t</array>\n')
        fd.write ('\t\t<key>RunAtLoad</key>\n')
        fd.write ('\t\t<true/>\n')
        fd.write ('\t\t<key>StandardOutPath</key>\n')
        fd.write ('\t\t<string>/var/log/postconfd.log</string>\n')
        fd.write ('\t\t<key>StandardErrorPath</key>\n')
        fd.write ('\t\t<string>/var/log/postconfd.err</string>\n')
        fd.write ('\t\t<key>Debug</key>\n')
        fd.write ('\t\t<true/>\n')
        fd.write ('\t</dict>\n')
        fd.write ('</plist>\n')

    # Programa de inicio que será ejecutado en el arranque de Mac OS X.
    with open (f'{mntdir}/var/root/postconfd.sh', 'w') as fd:
        fd.write ('#!/bin/bash\n')
        fd.write ('# postconfd - ejecución de scripts de inicio.\n')
        fd.write ('\n')
        fd.write ('# Ejecutar postconfiguración si existe el fichero indicador.\n')
        fd.write ('if [ -e /osxpostconf ]; then\n')
        fd.write ('\t# Tomar nombre del equipo.\n')
        fd.write (f'\tHOST="{host}"\n')
        fd.write ('\tif [ -z "$HOST" ]; then\n')
        fd.write ('\t\t# Si no hay nombre asociado, activar la red para obtener datos del DHCP.\n')
        fd.write ('\t\tsource /etc/rc.common\n')
        fd.write ('\t\tCheckForNetwork\n')
        fd.write ('\t\twhile [ "$NETWORKUP" != "-YES-" ]; do\n')
        fd.write ('\t\t\tsleep 5\n')
        fd.write ('\t\t\tNETWORKUP=\n')
        fd.write ('\t\t\tCheckForNetwork\n')
        fd.write ('\t\tdone\n')
        fd.write ('\t\t# Componer nombre del equipo a partir de datos del DHCP.\n')
        fd.write ('\t\tIP=$(ifconfig en0 inet | awk \'{if ($1=="inet") print $2}\')\n')
        fd.write ('\t\tHOST="mac-$(echo ${IP//./-} | cut -f3-4 -d-)"\n')
        fd.write ('\tfi\n')
        fd.write ('\t# Asignar nombre del equipo.\n')
        fd.write ('\tscutil --set ComputerName "$HOST"\n')
        fd.write ('\tscutil --set LocalHostName "$HOST"\n')
        fd.write ('\tscutil --set HostName "$HOST"\n')
        fd.write ('\thostname "$HOST"\n')
        fd.write ('\t# Descromprimir ficheros de versión para obtener inventario de aplicaciones.\n')
        fd.write ('\tfind /Applications -type d -name "*.app" -prune -exec \\n')
        fd.write ('\t     ditto --nopreserveHFSCompression "{}/Contents/version.plist" "{}/Contents/version.plist.uncompress"\n')
        fd.write ('\trm -f /osxpostconf    # Borrar fichero indicador de psotconfiguración\n')
        fd.write ('fi\n')
    os.chmod (f'{mntdir}/var/root/postconfd.sh', 0o700)    # Dar permiso de ejecución.
    PostConfLib.ogConfigureOgagent (disk, par)             # Configurar nuevo agente OGAgent de sistema operativo.

sys.exit (0)
