#!/usr/bin/python3
# lastact: arturo@2024-03-07
# desc: Configura en los PPDs los parámetros indicados como parámetros

# Para recoger los parametros pasados en la llamada al script:
import argparse

# Importamos textwrap para poder hacer uso de un epilogo de ejemplos al final de la ayuda de varias lineas, tal como indica la doc de argparse:
# https://docs.python.org/es/3/library/argparse.html
import textwrap

# Importamos sys para poder pasar los parámetros desde la función de inicio a la función main:
import sys

# Para hacer llamadas al sistema:
import os

# Para hacer uso de expresiones regulares:
import re


# Obtener el nombre del script
nombre_script = os.path.basename(__file__)

# Definir el epílogo con ejemplos:
epilogo = f"""
Ejemplos de uso:
{nombre_script} '-i|--input' 'ruta_fichero_in.ppd' '-o|--output' 'ruta_fichero_out.ppd' '--konica-segumiento-cuenta' ...
{nombre_script} '-i|--input' 'ruta_fichero_in.ppd' '-o|--output' 'ruta_fichero_out.ppd' '--konica-user-authentication' ...
{nombre_script} '-c|--custom' "{{'directiva1': 'valor1', 'directiva2': 'valor2', ...}}" ...
"""

# Definimos las listas predefinidas de parámetros PPD:
lista_konica_user_authentication = {
    "DefaultKMAuthentication": "Private",
    "DefaultKMAuthServer": 1,
    "DefaultKMAuthUser": "None",
    "DefaultKMAuthPass": "Custom.1234",
}
lista_konica_seguimiento_cuenta = {
    "DefaultKMSectionManagement": "True",
    "DefaultKMAccPass": "Custom.1234",
}


def mostrar_ayuda():
    parser.print_help()


def cadena_to_diccionario(_cadena):
    _lista = {}
    _parejas = _cadena.split(";")
    for _pareja in _parejas:
        if ":" in _pareja:
            _clave,_valor = _pareja.split(": ")
            _lista[_clave] = _valor
    return _lista

def ppd_asignar_lista_parametros(contenido, _lista, _texto):
    # _texto = "#> Modificaremos las siguientes directivas relativas a la autenticación en konica:"
    # _lista = lista_konica_user_authentication
    if not isinstance(_lista, dict):
        print (f"#> Warning: La lista suministrada no es un diccionario: {_lista}. Pasamos a transformarlo en diccionario")
        _lista = cadena_to_diccionario(_lista)
    print(_texto)
    for key in sorted(_lista):
        print(key, _lista[key])
        regex = f"{key}: .*"
        sustitucion = f"{key}: {_lista[key]}"
        if re.search(regex, contenido):
            print(f"+> Se ha encontrado el patrón: '{regex}' => '{sustitucion}'")
            contenido = re.sub(regex, sustitucion, contenido)
        else:
            print(f"-> NO se ha encontrado el patrón: '{regex}' ('{sustitucion}')")
    return contenido


def main(argv):
    if os.path.isfile(args.input):
        dir_base = os.path.dirname(os.path.abspath(args.input))
        destino = dir_base + "/" + args.output
        print(f"El archivo PPD a manipular es: {args.input}, ubicado en: {dir_base}")
        print(f"Destino: {destino}")
        # print(os.path.abspath(args.input))
    else:
        # Si el archivo no existe, imprimir un mensaje de error
        print("El archivo PPD indicado no existe")
        os._exit(1)

    try:
        fhand = open(args.input)
        contenido = fhand.read()
    except:
        mensaje = "=> El archivo indicado como parámetro no existe: " + args.input
        print(mensaje)
        os._exit(2)

    # Comprobamos que parámetros se han pasado para generar el archivo de salida:
    if args.konica_user_authentication:
        texto = f"#> Modificaremos las siguientes directivas relativas a la autenticación en konica: {lista_konica_user_authentication}"
        contenido = ppd_asignar_lista_parametros(
            contenido, lista_konica_user_authentication, texto
        )

    if args.konica_seguimiento_cuenta:
        texto = f"#> Modificaremos las siguientes directivas relativas a la account track o seguimiento de cuenta de konica: {lista_konica_seguimiento_cuenta}"
        contenido = ppd_asignar_lista_parametros(
            contenido, lista_konica_seguimiento_cuenta, texto
        )

    if args.custom_params:
        lista = args.custom_params
        texto = f"#> Personalizaremos las siguientes directivas indicadas manualmente: {lista}"
        contenido = ppd_asignar_lista_parametros(
            contenido, eval(lista), texto
        )  # Mediante eval() transformamos una cadena de texto en un diccionario

    # Guardamos el resultado en el fichero de salida:
    try:
        fout = open(destino, "w")
        fout.write(contenido)
    except:
        mensaje = "=> ¡¡Error!! No hay permiso de escritura sobre el archivo ..."
        print(mensaje)
        os._exit(3)
    print(f"=> PPD resultante: {destino}")


# Creamos un objeto argparse para la ayuda y tratamiento de los parámetros:
parser = argparse.ArgumentParser(
    description="Configura los parámetros PPD de los ficheros PPDs pasados como parámetro.",
    formatter_class=argparse.RawDescriptionHelpFormatter,
    epilog=textwrap.dedent(epilogo),
)
parser.add_argument(
    "-i",
    "--input",
    help="Indica la ruta del archivo PPD a tomar como patrón y modificar",
    required=True,
)
parser.add_argument(
    "-o",
    "--output",
    help="Indica el nombre del archivo PPD resultante de salida",
    required=True,
)
parser.add_argument(
    "--konica-segumiento-cuenta",
    action="store_true",  # Permite definir un argumento sin valor que le acompañe
    dest="konica_seguimiento_cuenta",  #  Permite comprobar mediante args.[dest] si el parámetro o argumento ha sido indicado
    help=f"Account Track: Modifica las directivas #> {lista_konica_seguimiento_cuenta}",
)
parser.add_argument(
    "--konica-user-authentication",
    action="store_true",
    dest="konica_user_authentication",
    help=f"User Authentication: Modifica las directivas relativas a la autenticación en konica #> {lista_konica_user_authentication}",
)
parser.add_argument(
    "-c",
    "--custom",
    dest="custom_params",
    help="Permite indicar una lista de parámetros a modificar #> {'directiva1': 'valor1', 'directiva2': 'valor2', ...}",
    required=False,
)
args = parser.parse_args()

if __name__ == "__main__":
    main(sys.argv[1:])
