#!/usr/bin/python3.11
# ------------------------------------------------------------------------------
# Copyright 2023 - 2024 Open Text.
#
# The only warranties for products and services of Open Text and its
# affiliates and licensors (“Open Text”) are as may be set forth in the
# express warranty statements accompanying such products and services.
# Nothing herein should be construed as constituting an additional
# warranty. Open Text shall not be liable for technical or editorial
# errors or omissions contained herein. The information contained herein
# is subject to change without notice.
#
# Except as specifically indicated otherwise, this document contains
# confidential information and a valid license is required for possession,
# use or copying. If this work is provided to the U.S. Government,
# consistent with FAR 12.211 and 12.212, Commercial Computer Software,
# Computer Software Documentation, and Technical Data for Commercial Items
# are licensed to the U.S. Government under vendor's standard commercial
# license.
# -------------------------------------------------------------------------

import json
import os, fnmatch
import shutil
import logging
import logging.handlers
import oes_cert_mgmt_utils

# Global variables
SERVICE_NAME = "nrm"
EDIR_RSA_SERVER_CERT_PATH = "/etc/ssl/servercerts/servercert.pem"
EDIR_ECDSA_SERVER_CERT_PATH = "/etc/ssl/servercerts/serverECcert.pem"
JSON_FILE_DIR= "/var/opt/novell/oes-cert-mgmt/servicecerts/"
PEM_FILE_PATH = "/var/opt/novell/oes-cert-mgmt/nrm.pem"
CONF_FILE_PATH = "/etc/opt/novell/httpstkd.conf"
CRT_SEARCH_STRING = "certfile="
LOG_PATH = "/var/opt/novell/log/oes-cert-mgmt/oes-cert-mgmt.log"

EXIT_CODES={
    "NOSSLCERT":201,
    "EDIRRSACERT":202,
    "EDIRECDSACERT":203,
    "OTHERCERT":204,
    "FAILURE":200,
}

json_data= {
               "servicename":SERVICE_NAME ,

            }

logger = logging.getLogger('Logger')
logLevel = oes_cert_mgmt_utils.getloglevel()
logger.setLevel(logLevel)

def initialize_logger():
    """
    To initialize logger.
    """

    rfh = logging.handlers.RotatingFileHandler(LOG_PATH, maxBytes=1024*1024*10, backupCount=2)
    formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s', '%m/%d/%Y %I:%M:%S')
    rfh.setFormatter(formatter)
    logger.addHandler(rfh)


def create_directory(dir):
    """
    Create directory if not present.
    """
    try:
        if not os.path.exists(dir):
            os.mkdir(dir)

    except Exception:
        logger.error("Failed to create directory: " + dir)

def get_cert_path(filePath, searchString):
    """
    Get the certificate path from the conf file

    """
    certificatePath = ""
    found = False
    try:
        with open(filePath,'r') as file:
            for line in file.readlines():
                line=line.strip()
                if not line.startswith(";") and not line.startswith("#"):
                    if searchString in line:
                        length=len(line)
                        start_index=line.find(searchString)
                        extracted_string= line[start_index:start_index+length]
                        splitting=(extracted_string.strip().split("="))
                        certificatePath = (splitting[1].strip())
                        certificatePath = certificatePath.split(" ")
                        certificatePath = (certificatePath[0].strip())
                        found = True

            if found == False:
                logger.error("NRM - "+ str(searchString)+" is not found in conf file")
                logger.info("NRM - the value of exitcode is "+ str(EXIT_CODES["FAILURE"]))
                exit(EXIT_CODES["FAILURE"])

    except FileNotFoundError as e:
        logger.warn("NRM - " + "File " + filePath + " not present")
    finally:
        if(file != None):
            file.close()

    return certificatePath

def to_check_symlink(path) :
    """
    To search if Certificate File Path is symlink or not.
    """
    return os.path.islink(path)

def other_cert(cert):
    """
    Update the json with the other cert path

    """
    json_data.update({"certpath":cert})
    if check_file_exists(cert):
        shutil.copy(cert,PEM_FILE_PATH)
    else:
        logger.error("NRM - certificatePath " + str(cert) + " not present")
        exit(EXIT_CODES["FAILURE"])

    json_data.update({"certpathtoprocess":PEM_FILE_PATH})
    write_to_json_file(JSON_FILE_DIR, SERVICE_NAME + '.json', json_data)


def check_file_exists(filePath):
    """
    Check if Certificate File Path exists.
    """
    return os.path.exists(filePath)

def write_to_json_file(target_path, target_file, data):
    """
    Search for a target_path and to generate the  json file.

    """
    if not check_file_exists(target_path):
        logging.error("NRM - JSON data directory " + target_path + " not present")
        exit(EXIT_CODES["FAILURE"])

    try:
        with open(os.path.join(target_path, target_file), 'w') as file:
            json.dump(data, file, indent=4)

    except Exception as e:
        logger.error(f"NRM - Failed to create the NRM json file\n" f"{e}")

    finally:

        if(file != None):
            file.close()

def main():
    initialize_logger()
    logger.info("NRM - Starting listing operation for NRM")
    certificatePath = get_cert_path(CONF_FILE_PATH , CRT_SEARCH_STRING)

    """
    If it is a symlink then we will get the corrsponding value.
    """
    if to_check_symlink(certificatePath):
        certificatePath = os.readlink(certificatePath)

    exitCode = EXIT_CODES["FAILURE"]

    if certificatePath == '':
        exitCode = EXIT_CODES["NOSSLCERT"]
    elif certificatePath == EDIR_RSA_SERVER_CERT_PATH:
        if check_file_exists(certificatePath) :
            exitCode = EXIT_CODES["EDIRRSACERT"]
        else :
            exitCode = EXIT_CODES["NOSSLCERT"]

    elif certificatePath == EDIR_ECDSA_SERVER_CERT_PATH:
        if check_file_exists(certificatePath) :
            exitCode = EXIT_CODES["EDIRECDSACERT"]
        else :
            exitCode = EXIT_CODES["NOSSLCERT"]
    elif certificatePath != '' and certificatePath != EDIR_RSA_SERVER_CERT_PATH and certificatePath != EDIR_ECDSA_SERVER_CERT_PATH :
        other_cert(certificatePath)
        exitCode = EXIT_CODES["OTHERCERT"]
    else:
        exitCode = EXIT_CODES["FAILURE"]

    logger.info("NRM - the value of exitcode is "+ str(exitCode) )
    exit(exitCode)

if __name__ == "__main__":
    main()
