const crypto = require('crypto');
const os = require('os');
const path = require('path');
const fs = require('fs');

function insecureHash(data) {

    if ((!data) || (typeof data !== 'string'))
        return;

    const hash = crypto.createHash('sha1').update(data).digest('hex');
    return hash.toUpperCase();
}

function secureHash(data) {

    return insecureHash([insecureHash(data), data].join(''));
}

function makeCertName(productId, cdbNumber, machineName) {

    return [
        insecureHash(productId),
        insecureHash(cdbNumber),
        insecureHash(machineName),
        '.dat'
    ].join('');
}

function connectionStringToObj(connectionString) {

    const result = {};
    if (connectionString)
        connectionString.split(';').forEach(function (keyValueString) {
            const kvp = keyValueString.split('=');
            kvp[1] && (result[kvp[0]] = kvp[1]);
        });

    return result;
}

function buildFileName(productId, cdbNumber, options) {

    options = options || {};

    const baseFolder = options['apiDataFolder'] || 'C:/ProgramData';
    const machineName = options['machineName'] || os.hostname().toUpperCase();

    const certFolderName = secureHash(productId);

    return path.join(
        baseFolder,
        'PatientApi',
        certFolderName,
        makeCertName(productId, cdbNumber, machineName));
}

function FileNameFromConnectionString(connectionString, options){

    const orgInfo = connectionStringToObj(connectionString);
    if (orgInfo['productId']) {
        return buildFileName(orgInfo['productId'], orgInfo['organisation'], options);
    }
}

function createEmptyFile(filename){

    const dirPath = path.dirname(filename);
    fs.mkdirSync(dirPath, { recursive: true });
    fs.closeSync(fs.openSync(filename, 'a'));
}

const hash = {};

exports.buildFileName = buildFileName;

exports.FileNameFromConnectionString = FileNameFromConnectionString;

exports.createApiCertFile = function(connectionString, options) {

    if (hash[connectionString] === true)
        return;

    const filename = FileNameFromConnectionString(connectionString, options);
    if (filename)
        createEmptyFile(filename);

    hash[connectionString] = true;
};

