/*
 * 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 {verifyToken} from "@typescript-auth/server";
import {SocketInterface} from "../../../modules/socket";
import {getCustomRepository} from "typeorm";
import {UserRepository} from "@chamesu/common/domains/auth/user/repository";
import {AuthUser} from "@chamesu/common/domains/auth/user";

function createAuthMiddleware(userCallback?: (socket: SocketInterface) => Promise<void>, guestCallback?: (socket: SocketInterface) => Promise<void>) {
    return function (socket: SocketInterface, next: CallableFunction) {
        socket.userId = undefined;
        socket.user = undefined;

        const auth : Record<string, any> = socket.handshake.auth;
        if(auth.hasOwnProperty('token')) {
            socket.userToken = auth.token;

            if (typeof auth.token !== 'undefined') {
                return verifyToken(auth.token)
                    .then(res => getCustomRepository(UserRepository).findOne(res.id ?? null))
                    .then((data: AuthUser | undefined) => {
                        if (typeof data === 'undefined') {
                            return next(new Error('Der Benuzter existiert nicht mehr...'));
                        }

                        socket.user = data;
                        socket.userId = socket.user.id;

                        if(typeof userCallback !== 'function') {
                            return next();
                        }

                        return userCallback(socket)
                            .then(() => {
                                return next();
                            })
                            .catch((e) => {
                                return next(e);
                            })
                    })
                    .catch((e: any) => {
                        console.log('Auth middleware: ' + e.message);
                        return next(e);
                    });
            }
        }

        if(typeof userCallback !== 'function') {
            return next();
        }

        return guestCallback(socket)
            .then(() => next())
            .catch(e => next(e));
    };
}

export default createAuthMiddleware;
