#!/usr/bin/python3

import os
import sys
import subprocess

import ogGlobals
import SystemLib
import CacheLib
import FileSystemLib
import DiskLib
import InventoryLib

#Load engine configurator from engine.cfg file.
#Carga el configurador del engine desde el fichero engine.cfg
## (ogGlobals se encarga)

# Clear temporary file used as log track by httpdlog
# Limpia los ficheros temporales usados como log de seguimiento para httpdlog
open (ogGlobals.OGLOGSESSION,        'w').close()
open (ogGlobals.OGLOGCOMMAND,        'w').close()
open (ogGlobals.OGLOGCOMMAND+'.tmp', 'w').close()

# Registro de inicio de ejecución
SystemLib.ogEcho (['log', 'session'], None, f'{ogGlobals.lang.MSG_INTERFACE_START} {sys.argv}')

# Solo ejecutable por OpenGnsys Client.
#path = os.getenv('PATH')
#if path:
#    os.environ['PATH'] = f"{path}:{os.path.dirname(__name__)}"
prog = os.path.basename(__name__)

#____________________________________________________________________
#
# El parámetro $2 es el que aporta toda la información y el $1 se queda obsoleto
# Formato de entrada:
#		dis=Número de disco
#		*=caracter de separación
#		che=Vale 0 o 1
#		*=caracter de separación
#		$tch=tamaño cache
#		!= caracter de separación
#
#   Y un numero indeterminado de cadenas del tipo siguuenteseparadas por el caracter '$':
#		par=Número de particion*cod=Código de partición*sfi=Sistema de ficheros*tam=Tamaño de la partición*ope=Operación
#		@= caracter de separación
#____________________________________________________________________

# Captura de parámetros (se ignora el 1er parámetro y se eliminan espacios y tabuladores).
#param='dis=1*che=0*tch=70000000!par=1*cpt=NTFS*sfi=NTFS*tam=11000000*ope=0%'
#param = ''.join(sys.argv[2:]).replace(' ', '').replace('\t', '')
param = sys.argv[2]

# Activa navegador para ver progreso
coproc = subprocess.Popen (['/opt/opengnsys/bin/browser', '-qws', 'http://localhost/cgi-bin/httpd-log.sh'])

# Leer los dos bloques de parámetros, separados por '!'.
tbprm = param.split ('!')
pparam = tbprm[0]  # General disk parameters
sparam = tbprm[1]  # Partitioning and formatting parameters

# Toma valores de disco y caché, separados por "*".
# Los valores están en las variables $dis: disco, $che: existe cache (1, 0), $tch: Tamaño de la cache.
tbprm = pparam.split ('*')
dis = tch = None
for item in tbprm:
    if '=' not in item: continue

    k, v = item.split ('=', 1)
    if k not in ['dis', 'tch']:
        print (f'ignoring unknown disk parameter ({k})')
        continue

    if   'dis' == k: dis = int (v)
    elif 'tch' == k: tch = v

# Error si no se define el parámetro de disco (dis).
if dis is None:
    coproc.kill()
    sys.exit (ogGlobals.OG_ERR_FORMAT)
if tch is None:
    tch = '0'

# Toma valores de distribución de particiones, separados por "%".
tbp = []  # Valores de configuración (parámetros para ogCreatePartitions)
tbf = {}  # Tabla de formateo

tbprm = sparam.split('%')

maxp=0
for item in tbprm:
    if not item: continue         ## por si nos pasan un '%' al final de todo
        # Leer datos de la partición, separados por "*".
    par = cpt = sfi = tam = None
    ope = 0
    for c in item.split ('*'):
        if '=' not in c: continue

        k, v = c.split ('=', 1)
        if k not in ['par', 'cpt', 'sfi', 'tam', 'ope']:
            print (f'ignoring unknown partition parameter ({k})')
            continue

        if   'par' == k: par = int (v)
        elif 'cpt' == k: cpt = v
        elif 'sfi' == k: sfi = v
        elif 'tam' == k: tam = v
        elif 'ope' == k: ope = int (v)

    missing_params = []
    if par is None: missing_params.append ('par')
    if cpt is None: missing_params.append ('cpt')
    if sfi is None: missing_params.append ('sfi')
    if tam is None: missing_params.append ('tam')
    if missing_params:
        print (f'partition data ({item}) missing required parameters ({' '.join (missing_params)})')
        coproc.kill()
        sys.exit (1)

        # Componer datos de particionado.
    if 'CACHE' != cpt: tbp.append (f'{cpt}:{tam}')
    if ope:
        # Si se activa operación de formatear, componer datos de formateo.
        if cpt not in ['EMPTY', 'EXTENDED', 'LINUX-LVM', 'LVM', 'ZPOOL']:
            tbf[par] = sfi
        # Obtener la partición mayor.
    if par > maxp: maxp = par

#____________________________________________________
#
# Proceso
#____________________________________________________
# Tamaño actual de la cache
CACHESIZE=CacheLib.ogGetCacheSize()

# Desmonta todas las particiones y la caché

SystemLib.ogEcho (['session', 'log'], None, f'[10] {ogGlobals.lang.MSG_HELP_ogUnmountAll}')
FileSystemLib.ogUnmountAll (dis)
CacheLib.ogUnmountCache()

# Elimina la tabla de particiones
cur_ptt = DiskLib.ogGetPartitionTableType (dis)
ptt = 'GPT' if InventoryLib.ogIsEfiActive() else 'MSDOS'
if not cur_ptt or ptt != cur_ptt:
    DiskLib.ogDeletePartitionTable (dis)
    SystemLib.ogExecAndLog ('command', DiskLib.ogUpdatePartitionTable)
    DiskLib.ogCreatePartitionTable (dis, ptt)

# Inicia la cache.
if 'CACHE' in sparam:
    SystemLib.ogEcho (['session', 'log'], None, f'[30] {ogGlobals.lang.MSG_HELP_ogCreateCache}')
    SystemLib.ogEcho (['session', 'log'], None, f'   initCache {tch}')
    rc = SystemLib.ogExecAndLog ('command', CacheLib.initCache, tch)
    if rc:
        SystemLib.ogRaiseError (['log', 'session'], ogGlobals.OG_ERR_CACHE, f'initCache failed')
        coproc.kill()
        sys.exit (1)

# Definir particionado.
SystemLib.ogEcho (['session', 'log'], None, f'[50] {ogGlobals.lang.MSG_HELP_ogCreatePartitions}')
SystemLib.ogEcho (['session', 'log'], None, f'   ogCreatePartitions {dis} {' '.join (tbp)}')
res = SystemLib.ogExecAndLog ('command', DiskLib.ogCreatePartitions, dis, tbp)
if not res:
    coproc.kill()
    SystemLib.ogRaiseError (['log', 'session'], ogGlobals.OG_ERR_GENERIC, f'ogCreatePartitions {dis} {' '.join (tbp)}')
    sys.exit (1)
SystemLib.ogExecAndLog ('command', DiskLib.ogUpdatePartitionTable)

#  Formatear particiones
SystemLib.ogEcho (['session', 'log'], None, f'[70] {ogGlobals.lang.MSG_HELP_ogFormat}')
retval = 0
for p in range (1, maxp+1):
    if p not in tbf: continue
    if 'CACHE' == tbf[p]:
        if CACHESIZE == tch:    # Si el tamaño es distinto ya se ha formateado.
            SystemLib.ogEcho (['session', 'log'], None, '   ogFormatCache')
            retval = SystemLib.ogExecAndLog ('command', CacheLib.ogFormatCache)
    else:
        SystemLib.ogEcho (['session', 'log'], None, f'   ogFormatFs {dis} {p} {tbf[p]}')
        retval = SystemLib.ogExecAndLog ('command', FileSystemLib.ogFormatFs, dis, str(p), tbf[p])
        if retval:
            coproc.kill()
            SystemLib.ogRaiseError (['session', 'log'], ogGlobals.OG_ERR_GENERIC, f'ogFormatFs  {dis} {p} {tbf[p]}')
            sys.exit (1)
# Registro de fin de ejecución
SystemLib.ogEcho (['session', 'log'], None, f'{ogGlobals.lang.MSG_INTERFACE_END} {retval}')

#___________________________________________________________________
#
# Retorno
#___________________________________________________________________

coproc.kill()
sys.exit (0)
