#!/usr/bin/python3
# Scirpt de iniciación de la caché local de disco.
# Nota: se usa como base para el programa de configuración de equipos de OpenGnsys Admin).
# Formato: initCache [int_ndisk [int_npart]] {-1 | 0 | int_size} [NOMOUNT]

import sys
import time
import subprocess

import ogGlobals
import SystemLib
import FileSystemLib
import CacheLib
import DiskLib

def main (NDISK, NPART, SIZE, MOUNT):
    TIME1 = time.time()

# Si tamaño=0, no hacer nada.
    if 0 == SIZE:
        print("No modificar la caché local.")
        return True

# Si tamaño=-1, borrar caché.
    if -1 == SIZE:
        print("[10] Trabajar sin caché local.")
        CacheLib.ogUnmountCache()
        CacheLib.ogDeleteCache()
    else:
    # Si la caché actual está definida en otro disco y partición, se elimina.
        current_cache = CacheLib.ogFindCache()
        if current_cache and f"{NDISK} {NPART}" != current_cache:
            print("[10] Detectada otra caché, eliminarla")
            CacheLib.ogUnmountCache()
            CacheLib.ogDeleteCache()

    # Tomamos el tamaño actual. Si no existe cache será 0.
        CACHESIZE = CacheLib.ogGetCacheSize()
        if not CACHESIZE: CACHESIZE = 0        ## may be None

    # Error si tamaño definido no es >0.
        if SIZE <= 0:
            SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f"!({SIZE}>0)")
            return False

    # Si no existe caché o si cambia su tamaño, crearla.
        if SIZE != CACHESIZE:
            print("[10] Crear partición de caché local.")
            CacheLib.ogUnmountCache()
            if not CacheLib.ogCreateCache (NDISK, NPART, SIZE):
                SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_CACHE, 'failed to create cache')
                return False
            DiskLib.ogUpdatePartitionTable()

    # Si caché no montada y no formateada o cambia el tamaño: formatear.
        cache = CacheLib.ogFindCache()
        if not cache:
            SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTCACHE, '')
            return False
        cache = cache.split()
        if not FileSystemLib.ogIsFormated (cache[0], cache[1]) or SIZE != CACHESIZE:
            print("[50] Formatear caché local.")
            CacheLib.ogFormatCache()
        print("[70] Comprobar montaje de caché local.")
    # Si error al montar, chequear sistema de archivos y volver a montar.
        if not CacheLib.ogMountCache():
            print("[80] Comprobar consistencia y volver a montar caché local.")
            FileSystem.ogCheckFs (cache[0], cache[1])
            if not CacheLib.ogMountCache():
                return False

    # Dejar desmontada la caché si se ha solicitado.
        if not MOUNT:
            print("[90] Dejar desmontada la caché local.")
            CacheLib.ogUnmountCache()

# Duración del proceso.
    TIME = time.time() - TIME1
    print (f"[100] Duración de la operación {int(TIME // 60)}m {int(TIME % 60)}s")
    return True

if __name__ == "__main__":
    PROG = sys.argv[0]
    EXECFORMAT = f"{PROG} [int_ndisk [int_npart]] {{-1 | 0 | int_size}} [NOMOUNT]"

    args = sys.argv[1:]
    if args and 'NOMOUNT' == args[-1].upper():
        MOUNT = False
        args = args[:-1]
    else:
        MOUNT = True

    PARAMS = len (args)
    try:
        if 1 == PARAMS:
            NDISK = 1
            NPART = 4
            SIZE = int (args[0])
        elif 2 == PARAMS:
            NDISK = int (args[0])
            NPART = 4
            SIZE = int (args[1])
        elif 3 == PARAMS:
            NDISK = int (args[0])
            NPART = int (args[1])
            SIZE = int (args[2])
        else:
            SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, EXECFORMAT)
            sys.exit (1)
    except ValueError:
        SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, EXECFORMAT)
        sys.exit (1)

    # Si disco o partición no son mayores o iguales que 1, error.
    if NDISK < 1 or NPART < 1:
        SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, EXECFORMAT)
        sys.exit (1)

    # Si tamaño no es numérico o tamaño<-1, error.
    if SIZE < -1:
        SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, EXECFORMAT)
        sys.exit (1)

    rc = main (NDISK, NPART, SIZE, MOUNT)
    sys.exit (not rc)
