
/*
 * Copyright (c) 2022.
 * Author Peter Placzek (tada5hi)
 * For the full copyright and license information,
 * view the LICENSE file that was distributed with this source code.
 */

import {Redis} from "ioredis";
import {
    RedisCacheEventEmitter,
    RedisExpireCacheOptions
} from "../../../../modules/redis/cache/event";

/*
interface RoomUserCacheOptions {
    redis: {
        prefix: string
    }
}

export class RoomUserCache<T extends {roomId: string, userId: number, [key: string]: number | string}> extends CacheTimeoutModule<T> {
    protected roomTimeoutKey : string = 'roomTimeout';
    protected userTimeoutKey : string = 'userTimeout';

    protected ctx: RoomUserCacheContext;

    protected options : RoomUserCacheOptions;

    //--------------------------------------------------------------------

    constructor(ctx: RoomUserCacheContext, options: RoomUserCacheOptions) {
        super();

        this.ctx = ctx;

        this.options = options;
    }

    //--------------------------------------------------------------------

    public getFullTimeoutKey(id: T) : string {
        return this.options.redis.prefix +
            this.roomTimeoutKey +
            ':' +
            id.roomId +
            ':' +
            this.userTimeoutKey +
            ':' +
            id.userId;
    }

    getFullTimeoutGlobalKey(): string {
        return this.options.redis.prefix +
            this.roomTimeoutKey +
            ':' +
            '[0-9a-zA-Z-]*' +
            ':' +
            this.userTimeoutKey +
            ':' +
            '[0-9]*';
    }

    public parseFullTimeoutKey(key: string) : T  {
        const parts = key.split(':');

        return {
            roomId: parts[1],
            userId: Number(parts[3])
        } as T;
    }

    protected async onTimeoutExpired(id: T): Promise<void> {
        if(
            id.hasOwnProperty('userId') &&
            id.hasOwnProperty('roomId')
        ) {
            const userId : number = id.userId;
            const roomId: string = id.roomId;

            await this.ctx.status.setUserOffline(roomId, userId);
            await this.ctx.event.emitUserOffline(roomId, userId);

            console.log('ChatRoom: #'+roomId+' User Status: user #'+id.userId+' timed out.');
        }
    }
}
*/
export class UserEventCache extends RedisCacheEventEmitter<{ roomId: string, userId: number }> {
    constructor(protected readonly redisDatabase: Redis, public readonly options: RedisExpireCacheOptions<any>) {
        super(redisDatabase, options);
    }
}

let roomUserCache : UserEventCache | undefined;

export function useChatRoomUserCache(redisDatabase: Redis) : UserEventCache {
    if(typeof roomUserCache !== 'undefined') {
        return roomUserCache;
    }

    if(typeof redisDatabase === 'undefined') {
        throw new Error('No context injected in room user cache handler...');
    }

    roomUserCache = new UserEventCache(redisDatabase, {
        prefix: 'chat',
        suffix: 'roomUser',
        seconds: 10,
        getKey: key => key.roomId+':'+key.userId
    });

    return roomUserCache;
}
