/*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/>.*/

//NPM Imports
const {mongoose} = require('mongoose');

//Local Imports
const defaultTokes = require("../../../defaultTokes.json");
const server = require('../../server');
const loggerUtils = require('../../utils/loggerUtils');

/**
 * Mongoose Schema representing a toke command
 */
const tokeCommandSchema = new mongoose.Schema({
    command:{
        type: mongoose.SchemaTypes.String,
        required: true
    }
});

/**
 * Pre-Save middleware, ensures tokebot receives all new toke commands
 */
tokeCommandSchema.pre('save', async function (next){
    //if the command was changed
    if(this.isModified("command")){
        //Get server tokebot object
        const tokebot = server.channelManager.chatHandler.chatPreprocessor.tokebot;

        //If tokebot is up and running
        if(tokebot != null && tokebot.tokeCommands != null){
            //Pop the command on to the end
            tokebot.tokeCommands.push(this.command);
        }
    }


    //All is good, continue on saving.
    next();
});

/**
 * Pre-Delete middleware, ensures tokebot removes all old toke commands
 */
tokeCommandSchema.pre('deleteOne', {document: true}, async function (next){
    //Get server tokebot object (isn't this a fun dot crawler? Why hasn't anyone asked me to stop writing software yet?)
    const tokebot = server.channelManager.chatHandler.chatPreprocessor.tokebot;

    //Get the index of the command within tokeCommand and splice it out
    tokebot.tokeCommands.splice(tokebot.tokeCommands.indexOf(this.command),1);

    //All is good, continue on deleting.
    next();
});

/**
 * Pulls command strings from DB and reports back
 * @returns {Array} Array of toke commands pulled from the DB
 */
tokeCommandSchema.statics.getCommandStrings = async function(){
    //Get all toke commands in the DB
    const tokeDB = await this.find({});
    //Create an empty array to hold the toke commands
    var tokeArray = [];

    //for all toke commands found in the database
    tokeDB.forEach((toke)=>{
        //Push the command string into the tokeArray
        tokeArray.push(toke.command);
    })

    //return the toke command strings from the database
    return tokeArray;
}

/**
 * Loads default tokes into the DB from flat file upon launch
 */
tokeCommandSchema.statics.loadDefaults = async function(){
    //Make sure registerToke function is happy
    const _this = this;

    //Ensure default comes first (.bind(this) doesn't seem to work here...)
    await registerToke(defaultTokes.default);

    //For each entry in the defaultTokes.json file
    defaultTokes.array.forEach(registerToke);

    async function registerToke(toke){
        try{
            //Look for toke matching the one from our file
            const foundToke = await _this.findOne({command: toke});

            //if the toke doesn't exist
            if(!foundToke){
                const tokeDB = await _this.create({command: toke});
                console.log(`Loading default toke command '!${toke}' into DB from defaultTokes.json`);
            }

        }catch(err){
            if(toke != null){
                loggerUtils.dumpError(err);
            }else{
                loggerUtils.consoleWarn("Error, null toke!");
            }
        }
    }
}

module.exports = mongoose.model("tokeCommand", tokeCommandSchema);