/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.*/

const config = require('../../config.json');
const csrfUtils = require('./csrfUtils');
const {userModel} = require('../schemas/user/userSchema');
const userBanModel = require('../schemas/user/userBanSchema');

module.exports.validateSocket = async function(socket, quiet = false){
    //If we're proxied use passthrough IP
    const ip = config.proxied ? socket.handshake.headers['x-forwarded-for'] : socket.handshake.address;

    //Look for ban by IP
    const ipBanDB = await userBanModel.checkBanByIP(ip);

    //If this ip is randy bobandy
    if(ipBanDB != null){
        //Make the number a little prettier despite the lack of precision since we're not doing calculations here :P
        const expiration = ipBanDB.getDaysUntilExpiration() < 1 ? 0 : ipBanDB.getDaysUntilExpiration();

        if(quiet){
            socket.disconnect();
        }else{
            //If the ban is permanent
            if(ipBanDB.permanent){
                //tell it to fuck off
                socket.emit("kick", {type: "kicked", reason: `The IP address you are trying to connect from has been permanently banned. Your cleartext IP has been saved to the database. Any associated accounts will be nuked in ${expiration} day(s).`});
            //Otherwise
            }else{
                //tell it to fuck off
                socket.emit("kick", {type: "kicked", reason: `The IP address you are trying to connect from has been temporarily banned. Your cleartext IP has been saved to the database until the ban expires in ${expiration} day(s).`});
            }
        }

        return false;
    }


    //Check for Cross-Site Request Forgery
    if(!csrfUtils.isRequestValid(socket.request)){
        if(quiet){
            socket.disconnect();
        }else{
            socket.emit("kick", {type: "disconnected", reason: "Invalid CSRF Token!"});
        }

        return false;
    }


    return true;
}

//socket.request.session is already trusted, we don't actually need to verify against DB for authorzation
//It's just a useful place to grab the DB doc, and is mostly a stand-in from when the only socket-related code was in the channel folder
module.exports.authSocketLite = async function(socket){
    const user = socket.request.session.user;

    if(user == null){
        return null;
    }

    //Set socket user and channel values
    socket.user = {
        id: user.id,
        user: user.user,
    };

    //return user object from session
    return user;
}

module.exports.authSocket = async function(socket){
    //Find the user in the Database since the session won't store enough data to fulfill our needs :P
    const userDB = await userModel.findOne({user: socket.request.session.user.user});

    if(userDB == null){
        return null;
    }

    //Set socket user and channel values
    socket.user = {
        id: userDB.id,
        user: userDB.user,
    };

    return userDB;
}

module.exports.getChannelName = function(socket){
    return socket.handshake.headers.referer.split('/c/')[1].split('/')[0];
}