const { execSync,spawn } = require('child_process');
const fs = require('fs');
const path = require('path');
const log = require('loglevel');

const constants = require('../models/constants');
const constantsXml = require('../models/constants-xml');
const enums = require('../models/enums');
const enumsXml = require('../models/enums-xml');

class HelpersCtrl {
    constructor () {}

    isObject = (object, property) => {
        let is = false;
        if (!!property) {
            is = (typeof object === 'object' && typeof object !== undefined && object !== null && Object.keys(object).length !== 0 && object.hasOwnProperty(property));
        } else {
            is = (typeof object === 'object' && typeof object !== undefined && object !== null && Object.keys(object).length !== 0);
        }
        return is;
    }

    xor = (a, b) => {
        let x = Math.max(a.length, b.length);
        const dest = Buffer.allocUnsafe(x);
        for (let i=0; i<x; i++) {
            dest[i] = a[i] ^ b[i];
        }
        return dest;
    }

    getBool = (val) => {
        let num = +val;
        return !isNaN(num) ? !!num : !!String(val).toLowerCase().replace(!!0,'');
    }

    getHHmm = (min) => {
        let m = min % 60;
        let h = Math.abs((min - m) / 60);
        return (min < 0 ? "-" : "+") + (h < 10 ? "0" : "") + h.toString() + (m < 10 ? ":0" : ":") + m.toString();
    }

    serialPortModuleFix = () => {
        const escposSerialportFile = path.join(process.cwd(), 'node_modules', 'escpos-serialport', 'index.js');
        const escposSerialportFileContent = fs.readFileSync(escposSerialportFile, 'utf8');
        let escposSerialportFileContentNew = escposSerialportFileContent.replace('const SerialPort', 'const { SerialPort }').replace('new SerialPort(port, options)', 'new SerialPort({path: port, baudRate: options.baudRate})');
        if (escposSerialportFileContent != escposSerialportFileContentNew) {
            fs.writeFileSync(escposSerialportFile, escposSerialportFileContentNew, 'utf8');
            return true;
        }
        return false;
    }

    samSmartCardLibStart = async () => {
        const samSmartCardLib = spawn('java', ['-jar', 'stationary-pos-server-0.0.0.jar'], {cwd: path.join(process.cwd(), 'libs', 'sam-smart-card')});
        return new Promise((started) => {
            samSmartCardLib.stdout.on('data', (data) => {
                if (data.includes('org.eclipse.jetty.server.Server - Started')) {
                    global.samSmartCardLibPid = samSmartCardLib.pid;
                    started(global.samSmartCardLibPid);
                }
            });
        });
    }

    samSmartCardLibStop = () => {
        if (global.samSmartCardLibPid) {
            execSync('taskkill /pid '+global.samSmartCardLibPid+' /f /t', {cwd: path.join(process.cwd())});
        }
    }

    getFareItemIssuedNumber = (terminalId, transactionCounter) => {
        return parseInt(parseInt(terminalId).toString(2).padStart(32, 0) + parseInt(transactionCounter).toString(2).padStart(32, 0), 2);
    }

    getTerminalId = (fareItemIssuedNumber) => {
        return parseInt(fareItemIssuedNumber.toString(2).padStart(64, 0).substring(0, 32), 2);
    }

    getTransactionCounter = (fareItemIssuedNumber) => {
        return parseInt(fareItemIssuedNumber.toString(2).padStart(64, 0).substring(32), 2);
    }

}

module.exports = HelpersCtrl;
