# Martin Konečnik, http://git.siwim.si/mkonecnik/test_signing
# Script is meant for testing if signing with Електронний ключ Алмаз-1К is working correctly.
from configparser import ConfigParser
from logging import DEBUG, basicConfig, getLogger

from EUSignCP import EUGetInterface, EULoad, EUUnload


def sign_data(pIface, def0_file: bytes) -> bytes:
    signed = list()
    try:
        pIface.SignDataInternal(True, def0_file, len(def0_file), None, signed)
    except Exception as e:
        logger_sign.error(f'SignData failed: {e}')
        pIface.Finalize()
        return None
    return signed[0]


def setup_encryption_interface(password: bytes) -> tuple:  # Returns tuple of EUGetInterface and info
    EULoad()
    pIface = EUGetInterface()
    try:
        pIface.SetUIMode(False)
        pIface.Initialize()
        pIface.SetUIMode(False)
    except Exception as e:
        logger_sign.info(f'Initialize failed: {e}')
        EUUnload()
        return None, None

    logger_sign.debug('Library Initialized')

    # # Set CMP
    # dSettings = {}
    # dSettings["bUseCMP"] = True
    # dSettings["szAddress"] = "http://acskidd.gov.ua"
    # dSettings["szPort"] = "80"
    # dSettings["szCommonName"] = ""
    # pIface.SetCMPSettings(dSettings)
    #
    # dSettings = {}
    # dSettings["bOfflineMode"] = False
    #
    # pIface.SetModeSettings(dSettings)

    dwType = 0
    lDescription = []
    try:
        pIface.EnumKeyMediaTypes(dwType, lDescription)
        while lDescription[0] != 'е.ключ ІІТ Алмаз-1К':
            dwType += 1
            if not pIface.EnumKeyMediaTypes(dwType, lDescription):
                logger_sign.error('KeyMedia not found')
                pIface.Finalize()
                EUUnload()
                return None, None

    except Exception as e:
        logger_sign.info(f'EnumKeyMediaTypes failed: {e}')
        pIface.Finalize()
        EUUnload()
        return None, None

    lDescription = []
    if not pIface.EnumKeyMediaDevices(dwType, 0, lDescription):
        logger_sign.error('Device not found')
        pIface.Finalize()
        EUUnload()
        return None, None
    logger_sign.debug(f'Device description: {lDescription[0]}')

    pKM = {'szPassword': password, 'dwDevIndex': 0, 'dwTypeIndex': dwType}
    try:
        pInfo = dict()  # Info about certificate is stored here.
        pIface.ReadPrivateKey(pKM, pInfo)
    except Exception as e:
        logger_sign.error(f'Key reading failed: {e}')
        pIface.Finalize()
        EUUnload()
        return None, None

    logger_sign.debug('Key success read')
    return pIface, pInfo


basicConfig(level=DEBUG)
logger_sign = getLogger('signing')

try:
    config = ConfigParser()
    config.read('../ua.conf', encoding='utf-8-sig')
    pwd = config['General']['pwd'].encode()
except Exception as e:
    logger_sign.error(f'An error has occurred parsing conf: {e}')
    pwd = b'siwim323'
logger_sign.info(f'Using password {pwd}.')

pIface, pInfo = setup_encryption_interface(pwd)
if pIface is not None:
    logger_sign.info(f'Signing successful! Signed data length: {len(sign_data(pIface, b"testing"))}')
else:
    logger_sign.error('Failed to read key!')

input('Press any key to exit ...')
