const logger = require('electron-log');
const path = require('path');
const os = require('os');
const arch = os.arch();
const platform = os.platform();
const fs = require('fs');

const isWindows = () => platform === 'win32'
const isMac = () => platform === 'darwin'

class QCFPlugin {
    constructor(isDev = false) {

        let dllPath = path.resolve(__dirname, './');
        let lib
        try {
            let fileMidPath = `${platform}-${arch}`;
            if (isWindows()) {
                if (os.arch() == 'x64') {
                    if (isDev) {
                        dllPath = path.resolve(__dirname, './win32-x64/');
                    } else {
                        dllPath = path.resolve(process.resourcesPath, './app.asar.unpacked/node_modules/@hysc/boom-cpp-plugin/qcfPlugin', fileMidPath);
                    }
                    process.env.PATH = dllPath + ';' + process.env.PATH;
                    lib = require(`./win32-x64/BoomGdPlugin.node`);
                } else {
                    dllPath = path.resolve(process.resourcesPath, './app.asar.unpacked/node_modules/@hysc/boom-cpp-plugin/qcfPlugin', fileMidPath);
                    process.env.PATH = dllPath + ';' + process.env.PATH;
                    lib = require(`./win32-ia32/BoomGdPlugin.node`);
                }
            } else if (isMac()) {
                if (isDev) {
                    dllPath = path.resolve(__dirname, './');
                } else {
                    dllPath = path.resolve(process.resourcesPath, './app.asar.unpacked/node_modules/@hysc/boom-cpp-plugin/qcfPlugin', fileMidPath);
                }
                
                const exists = fs.existsSync(dllPath);
                console.log('cpp plugin dllPath:', dllPath, 'exists:', exists)
                if (os.arch() == 'arm64' && exists) {
                    process.env.PATH = dllPath + ';' + process.env.PATH;
                    lib = require(`./darwin-arm64/BoomGdPlugin.node`);
                } else {
                    fileMidPath = 'darwin-x64';
                    if (isDev) {
                        dllPath = path.resolve(__dirname, './');
                    } else {
                        dllPath = path.resolve(process.resourcesPath, './app.asar.unpacked/node_modules/@hysc/boom-cpp-plugin/qcfPlugin', fileMidPath);
                    }
                    process.env.PATH = dllPath + ';' + process.env.PATH;
                    lib = require(`./darwin-x64/BoomGdPlugin.node`);
                }
            }
        }
        catch (error) {
            logger.log('gd: dllPath:', dllPath)
            logger.log('gd: load node error', error);
        }

        logger.log('gd:dllpath:', dllPath);
        try {
            const instanse = new lib.BoomGdPlugin();
            this.instance = instanse;
            logger.log('gd: instance init success', this.instance, os.arch());
        } catch (error) {
            logger.log('gd: init error:', error);
        }

    }
    /**
     * 预激活
     * @param path 
     * @param logPath 
     * @param ukeyType 不传默认是6, U盾传8
     * @returns 
     */
    preActivate(path, logPath, ukeyType) {
        this.checkSafe()
        return this.instance.preActivate(path, logPath, ukeyType)
    }
    async reportSPMWithSignPubkey(algName, CspAddr, port) {
        this.checkSafe();
        const res = await this.instance.reportSPMWithSignPubkey(algName, CspAddr, port);
        res.hexCode = res.code.toString(16)
        return res;
    }
    setKeyFilePath(path) {
        this.checkSafe();
        return this.instance.setKeyFilePath(path);
    }
    setCustomConfig(customItemName, path) {
        this.checkSafe();
        return this.instance.setCustomConfig(customItemName, path);
    }
    /**
     * 国盾初始化
     * @param useCspInfo
     * @param appType
     * @param appAccount
     * @param cspID
     * @returns
     */
    async init(appType, appAccount, cspID, cspIP='qkeys.cn', cspPort=18000) {
        this.checkSafe();
        const res = await this.instance.init(appType, appAccount, cspID, cspIP, cspPort);
        res.hexCode = res.code.toString(16)
        return res
    }
    /** 入网认证(基于公钥) */
    async auth_pubkey(appType, appAccount, cspID, cspIP='qkeys.cn', cspPort=18000) {
        this.checkSafe();
        const res = await this.instance.auth_pubkey(appType, appAccount, cspID, cspIP, cspPort);
        return {
            code: res.code,
            hexCode: res.code.toString(16),
            message: res.message,
            token: res.token,
            tokenValidSeconds: res.tokenValidSeconds
        };
    }
    /** 充注 */
    async fillKey(serverInfo) {
        this.checkSafe();
        return await this.instance.fillKey(serverInfo);
    }
    finish() {
        console.log('gd:finish')
        this.checkSafe();
        const res = this.instance.finish();
        //this.instance = null;
        return res;
    }
    /** 获取密钥量信息 */
    async getSPMKeyInfo(phoneNumber, pin) {
        this.checkSafe();
        return await this.instance.getSPMKeyInfo(phoneNumber, pin);
    }
    /**
     * 入网认证函数
     */
    async auth() {
        this.checkSafe();
        const res = await this.instance.auth();
        return {
            code: res.code,
            hexCode: res.code.toString(16),
            message: res.message,
            token: res.token,
            tokenValidSeconds: res.tokenValidSeconds
        };
    }
    /**
     * 密钥续充  先去判断密钥量<50去续充 续充
     * @param token  用户入网认证获得的令牌
     * @param kenLen  要续充的密钥长度
     * @param reFillFlag  续充模式（0：追加模式，1：覆盖模式）
     * @returns 返回：成功返回RET_OK，失败返回错误码
     */
    async reFillKey(token, kenLen, reFillFlag) {
        this.checkSafe();
        return await this.instance.reFillKey(token, kenLen, reFillFlag);
    }

    reFillKeySync(token, kenLen, reFillFlag) {
        this.checkSafe();
        return this.instance.reFillKeySync(token, kenLen, reFillFlag);
    }
    /**
     * 生成组-跨平台
     * @param token  认证令牌句柄
     * @param groupKeyLen  申请组密钥的长度（16整数倍），最大支持256字节
     * @param groupName 组名称
     * @returns groupID 组ID
     */
    async createGroup(token, groupKeyLen, groupName) {
        this.checkSafe();
        return await this.instance.createGroup(token, groupKeyLen, groupName);
    }
    /**
     * 生成组-跨平台-ex
     * @param token  认证令牌句柄
     * @param groupKeyLen  申请组密钥的长度（16整数倍），最大支持256字节
     * @param groupName 组名称
     * @returns groupID 组ID
     */
    async createGroupEx(token, groupKeyLen, groupName) {
        this.checkSafe();
        return await this.instance.createGroupEx(token, groupKeyLen, groupName);
    }
    /**
     * 根据组ID申请组密钥
     * @param token  认证令牌句柄
     * @param groupID  组标识
     * @returns	groupKey
     */
    async applyKeyWithGroupID(token, groupID) {
        this.checkSafe();
        return await this.instance.applyKeyWithGroupID(token, groupID);
    }
    hello(name) {
        return this.instance.hello(name);
    }
    setLogCallback(callback) {
        this.checkSafe();
        return this.instance.setLogCallback(callback);
    }
    setEventCallback(key, callback) {
        return this.instance.setEventCallback(key, callback);
    }
    checkSafe() {
        if (!this.instance) {
            throw new Error('guodun 实例未初始化');
        }
    }
}

module.exports = QCFPlugin;
