const EnumSessionWorker = Object.freeze({
    MESSAGE: 'SessionWorker.MESSAGE',
    START: 'SessionWorker.START',
    CLEAR: 'SessionWorker.CLEAR',
    TIMEOUT: 'SessionWorker.TIMEOUT',
});

class SessionWorkerManager {
    /** 
     * worker
     * @type {(Worker|null)}
     */
    activeWorker = null;
    /** Milliseconds to expire session */
    sessionExpiredTimeout = 60000 * 30;
    setSessionExpiredTimeout(sessionExpiredTimeout){
        this.sessionExpiredTimeout = sessionExpiredTimeout;
    }
    /**
     * function execute on session timeout
     * @type {Function}
     */
    expireFunction = null;
    setExpireFunction(expireFunction){
        this.expireFunction = expireFunction;
    }

    name(message){
        return `[SessionWorkerManager]: ${message}`;
    }

    /**
     * Initialize the worker and set the expireFunction
     * @param {Function} expireFunction function execute on session timeout
     */
    start() {
        if (window.Worker) {
            console.log(this.name('start Worker conversation'));
            this.activeWorker = new Worker('sessionWorker.js');
            this.activeWorker.onmessage = this._messageRecieverHandler.bind(this);

            this._message("SONO WORKER... SESSION WORKER");
            this._sendData(EnumSessionWorker.START, this.sessionExpiredTimeout);
        }
    }

    clear() {
        if (this.activeWorker) this._sendData(EnumSessionWorker.CLEAR);
    }

    end() {
        if (this.activeWorker) {
            this.activeWorker.terminate();
            delete this.activeWorker;
        }
    }

    /**
     * Message from Worker
     * @param {MessageEvent} ev message event
     */
     _messageRecieverHandler(ev){
        const { type, data } = ev.data;

        switch (type) {
            case EnumSessionWorker.TIMEOUT:
                console.log(this.name('session timeout'));
                if (this.expireFunction) this.expireFunction();
                this.end();
            break;

            default:
                console.log(this.name('message recieved'), { type, data });
        }
    }

    /**
     * Send string message to active worker
     * @param {string} message
     */
    _message(message) {
        this._sendData(EnumSessionWorker.MESSAGE, message);
    }

    /**
     * Send message to active worker
     * @param {string} type 
     * @param {*} data 
     */
    _sendData(type, data){
        if (this.activeWorker) {
            console.log(this.name('send data'), {type, data})
            this.activeWorker.postMessage({ type, data });
        }
    }
}



export default new SessionWorkerManager();