const { LogType } = require("loguix")
const fs = require("fs")
const path = require("path")
const { __glob } = require("./global-variables.js")
const auth = require("./auth.js")
const users = require("./users.js")
const files = require("./files.js")
const config = require("./config.js")
const links = require("./links.js")
const service = require("./services.js")
const pipeline = require("./pipelines.js")
const plog = new LogType("Web")
const cook = require("cookie")
const http = require("http")
const servermetrics = require("./server-metrics.js")
const pm2 = require('pm2');

/**
 * NOTE INTERNE
 * 
 * Changer les pictures de users autre part
 */

/**
 * 
 * @param {http.Server} server 
 */

module.exports.serverIO = function(server) {

    const io = require('socket.io')(server, {
        maxHttpBufferSize: 1e8,
        pingTimeout: 60000
    })

   
    io.on("connection", (socket) => {

        let token = cook.parse(socket.handshake.headers.cookie).token
        var user = auth.getUserByToken(token)

        if(user) {
            plog.log("Connexion au panel par '" + user.username + "' avec le socket : " + socket.id)
            user.setLastLogin(new Date())
            /**
             * GET REQUEST
             */ 

            // Get Users
            GetRequest("USERINFO", () => {
                user = auth.getUserByToken(token)
                GetAnswer("USERINFO", {username: user.username, display_name: user.display_name ,picture: user.picture, permission: user.permission})
            })

            /**
             * POST REQUEST
             */

            if(user.checkPermission("FILES_EXPLORER")) {

                PostRequest("FX_GET", (root) => {

                    PostAnswer("FX_GET", files.getFiles(root))
                })

                PostRequest("FX_NEW_FOLDER", (root) => {

                    PostAnswer("FX_NEW_FOLDER", files.createFolder(root))
                })

                PostRequest("FX_DELETE", (root) => {

                    PostAnswer("FX_DELETE", files.deleteFile(root))
                } )

                PostRequest("FX_RENAME", (settings) => {
                        
                    PostAnswer("FX_RENAME", files.renameFile(settings))
                }) 

                PostRequest("FX_SHARE", (settings) => {
                            
                    PostAnswer("FX_SHARE", files.shareFile(settings))
                })

                PostRequest("FX_GETFILE", (root) => {
                        
                    PostAnswer("FX_GETFILE", files.getFile(root))
                })

                PostRequest("FX_SAVEFILE", (settings) => {
                        
                    PostAnswer("FX_SAVEFILE", files.saveFile(settings))
                })

                PostRequest("FX_NEW_FILE", (settings) => {
                            
                    PostAnswer("FX_NEW_FILE", files.newFile(settings))
                }) 
                
                PostRequest("FX_UPLOAD", (settings) => {

                    PostAnswer("FX_UPLOAD", files.uploadFile(settings))

                })

                PostRequest("FX_PASTE", (settings) => {
                        
                    PostAnswer("FX_PASTE", files.pasteFile(settings))
                })

            } 

            if(user.checkPermission("SERVICES")) {

                PostRequest("SV_GET_SERVICE_STATUS", async (sv) => {
                    PostAnswer("SV_GET_SERVICE_STATUS", {answer: await service.getServiceStatus(sv), name: sv})
                })  

                PostRequest("SV_START_SERVICE", async (sv) => {
                    PostAnswer("SV_START_SERVICE", {answer: await service.startService(sv), name: sv})
                })

                PostRequest("SV_STOP_SERVICE", async (sv) => {
                    PostAnswer("SV_STOP_SERVICE", {answer: await service.stopService(sv), name: sv})
                })

                PostRequest("SV_RESTART_SERVICE", async (sv) => {
                    PostAnswer("SV_RESTART_SERVICE", {answer: await service.restartService(sv), name: sv})
                })

            }

            if(user.checkPermission("LINKS")) {
                PostRequest("LINKS_GET_ALL", () => {
                    PostAnswer("LINKS_GET_ALL", {answer: "OK", links: links.getLinks()})
                })

                PostRequest("LINKS_ADD", (settings) => {
                    PostAnswer("LINKS_ADD", {answer: links.addLink(settings)})
                })

                PostRequest("LINKS_DELETE", (id) => {
                    PostAnswer("LINKS_DELETE", links.removeLink(id))
                })

                PostRequest("LINKS_EDIT", (settings) => {
                    PostAnswer("LINKS_EDIT", links.updateLink(settings.id, settings))
                })


            }

            if(user.checkPermission("SERVERS")) {
                PostRequest("SERVER_GET_METRICS_Alpha", async (settings) => {
                    PostAnswer("SERVER_GET_METRICS_Alpha", {answer: "OK", metrics: await servermetrics.getMetrics(settings), name: settings});
                });
                PostRequest("SERVER_GET_METRICS_Omega", async (settings) => {
                    PostAnswer("SERVER_GET_METRICS_Omega", {answer: "OK", metrics: await servermetrics.getMetrics(settings), name: settings});
                });
            }

            if(user.checkPermission("PIPELINES")) {
                GetRequest("PL_GET_ALL", async () => {
                    GetAnswer("PL_GET_ALL", await pipeline.getAllPipelines())
                })

                PostRequest("PL_START", async (settings) => {
                    PostAnswer("PL_START", await pipeline.startPipeline(settings))
                })

            }

            if(user.checkPermission("USERS")) {
                GetRequest("US_ALL", async () => {
                    GetAnswer("US_ALL", await users.getAllUsers())
                })

                PostRequest("US_ADD", async (settings) => {
                    PostAnswer("US_ADD", await users.addUser(settings))
                })

                PostRequest("US_DELETE", async (settings) => {
                    PostAnswer("US_DELETE", await users.deleteUser(settings))
                })

                PostRequest("US_EDIT", async (settings) => {
                    PostAnswer("US_EDIT", await users.editUser(settings))
                })
            }

            if(user.checkPermission("SETTINGS")) {
                PostRequest("SETTINGS_SAVE", async (settings) => {
                    PostAnswer("SETTINGS_SAVE", await config.saveSettings(settings))
                })
                PostRequest("SERVER_RESTART", async () => {
                    pm2.restart('Neutral')
                })
                PostRequest("SERVER_STOP", async () => {
                    pm2.stop('Neutral')
                })
                GetRequest("SERVER_GET_LOGS", async () => {
                    GetAnswer("SERVER_GET_LOGS", await fs.readdirSync(__glob.LOGS))
                })

                PostRequest("SERVER_READ_LOG", async (logs) => {
                    PostAnswer("SERVER_READ_LOG", await fs.readFileSync(__glob.LOGS + path.sep + logs).toString())
                })

                GetRequest("SETTINGS_GET", async () => {
                    GetAnswer("SETTINGS_GET", await config.getSettings())
                })
            }


            socket.on("disconnect", (reason) => {
                plog.log("Déconnexion du panel par '" + user.username + "' avec le socket : " + socket.id)
            })

            socket.on("connect_error", (err) => {
                console.log(err)
                console.log(err.message); // prints the message associated with the error
              });

            function GetRequest(GQname, GQcallback) {
                socket.on("GET/" + GQname, () => {
                
                    plog.log(user.username + " - Socket : " + socket.id  + " - GET/" + GQname + " - [RECIEVED]") 
                    GQcallback()
                })
        
            }
    
            function GetAnswer(GRname, GRvalue) {
            
                plog.log(user.username + " - Socket : " + socket.id  + " - GET/" + GRname + " - [ANSWERED]") 
                socket.emit("ANSWER/GET/" + GRname, GRvalue)
    
            }

            function PostRequest(GQname, GQcallback) {
                socket.on("POST/" + GQname, (value) => {
                    plog.log(user.username + " - Socket : " + socket.id  + " - POST/" + GQname + " - [RECIEVED]") 
                    GQcallback(value)
                })
        
            }
    
            function PostAnswer(GRname, GRvalue) {
            
                plog.log(user.username + " - Socket : " + socket.id  + " - POST/" + GRname + " - [ANSWERED]") 
                socket.emit("ANSWER/POST/" + GRname, GRvalue)
    
            }

        } else {

            socket.disconnect()
            plog.warn("Connexion directe vers le panel avec un token inexistant : " + this.token)
        }
        

        
    
       
    })


}
