const fs = require('fs');
const url = require('url');
const http = require('http');
const https = require('https');
const express = require('express');
const app = express()
module.exports = function(s,config,lang,io){
    app.disable('x-powered-by');
    //get page URL
    if(!config.baseURL){
        config.baseURL = ""
    }else if(config.baseURL !== ''){
        config.baseURL = s.checkCorrectPathEnding(config.baseURL)
    }
    //Render Configurations - Web Paths
    if(config.webPaths === undefined){config.webPaths={}}
        //main access URI
        if(config.webPaths.home === undefined){config.webPaths.home='/'}
        //Super User URI
        if(config.webPaths.super === undefined){config.webPaths.super='/super'}
        //Admin URI
        if(config.webPaths.admin === undefined){config.webPaths.admin='/admin'}
        //Libraries URI
        if(config.webPaths.libs === undefined){config.webPaths.libs='/libs'}
        //API Prefix
        if(config.webPaths.apiPrefix === undefined){config.webPaths.apiPrefix = s.checkCorrectPathEnding(config.webPaths.home)}else{config.webPaths.apiPrefix = s.checkCorrectPathEnding(config.webPaths.apiPrefix)}
        //Admin API Prefix
        if(config.webPaths.adminApiPrefix === undefined){config.webPaths.adminApiPrefix=s.checkCorrectPathEnding(config.webPaths.admin)}else{config.webPaths.adminApiPrefix = s.checkCorrectPathEnding(config.webPaths.adminApiPrefix)}
        //Super API Prefix
        if(config.webPaths.superApiPrefix === undefined){config.webPaths.superApiPrefix=s.checkCorrectPathEnding(config.webPaths.super)}else{config.webPaths.superApiPrefix = s.checkCorrectPathEnding(config.webPaths.superApiPrefix)}
    //Render Configurations - Page Render Paths
    if(config.renderPaths === undefined){config.renderPaths={}}
        //login page
        if(config.renderPaths.index === undefined){config.renderPaths.index='pages/index'}
        //dashboard page
        if(config.renderPaths.home === undefined){config.renderPaths.home='pages/home'}
        //sub-account administration page
        if(config.renderPaths.admin === undefined){config.renderPaths.admin='pages/admin'}
        //superuser page
        if(config.renderPaths.super === undefined){config.renderPaths.super='pages/super'}
        //2-Factor Auth page
        if(config.renderPaths.factorAuth === undefined){config.renderPaths.factorAuth='pages/factor'}
        //Streamer v1 (Dashcam Prototype) page
        if(config.renderPaths.streamer === undefined){config.renderPaths.streamer='pages/streamer'}
        //Streamer v2 (Dashcam) page
        if(config.renderPaths.dashcam === undefined){config.renderPaths.dashcam='pages/dashcam'}
        //embeddable widget page
        if(config.renderPaths.embed === undefined){config.renderPaths.embed='pages/embed'}
        //timelapse page (not modal)
        if(config.renderPaths.timelapse === undefined){config.renderPaths.timelapse='pages/timelapse'}
        //mjpeg full screen page
        if(config.renderPaths.mjpeg === undefined){config.renderPaths.mjpeg='pages/mjpeg'}
        //gridstack only page
        if(config.renderPaths.grid === undefined){config.renderPaths.grid='pages/grid'}
        //slick.js (cycle) page
        if(config.renderPaths.cycle === undefined){config.renderPaths.cycle='pages/cycle'}
    // Use uws/cws
    if(config.useUWebsocketJs === undefined){config.useUWebsocketJs=true}
    if(config.webBlocksPreloaded === undefined){
        config.webBlocksPreloaded = [
            'home/initial',
            'home/videoPlayer',
            'home/monitorsList',
            'home/subAccountManager',
            'home/accountSettings',
            'home/apiKeys',
            'home/monitorSettings',
            'home/schedules',
            'home/monitorStates',
            'home/liveGrid',
            'home/regionEditor',
            'home/timelapseViewer',
            'home/eventFilters',
            'home/cameraProbe',
            'home/onvifScanner',
            'home/onvifDeviceManager',
            'home/configFinder',
            'home/logViewer',
            'home/calendar',
            'home/eventListWithPics',
            'home/fileBin',
            'home/videosTable',
            'home/studio',
            'home/monitorMap',
            'home/timeline',
            'confirm',
            'home/help',
        ]
    }
    //SSL options
    var wellKnownDirectory = s.mainDirectory + '/web/.well-known'
    if(fs.existsSync(wellKnownDirectory))app.use('/.well-known',express.static(wellKnownDirectory))
    config.sslEnabled = false
    const sslInfo = config.ssl
    if(sslInfo && sslInfo.key && sslInfo.cert){
        try{
            sslInfo.key = fs.readFileSync(s.checkRelativePath(sslInfo.key),'utf8')
            sslInfo.cert = fs.readFileSync(s.checkRelativePath(sslInfo.cert),'utf8')
            sslInfo.port = sslInfo.port || 443
            sslInfo.bindip = sslInfo.bindip || config.bindip
            if(sslInfo.ca && sslInfo.ca instanceof Array){
                sslInfo.ca.forEach(function(v,n){
                    sslInfo.ca[n] = fs.readFileSync(s.checkRelativePath(v),'utf8')
                })
            }
            var serverHTTPS = https.createServer(sslInfo,app);
            serverHTTPS.listen(sslInfo.port,config.bindip,function(){
                console.log('SSL '+lang.Shinobi+' : SSL Web Server Listening on '+sslInfo.port);
            });
            if(config.webPaths.home !== '/'){
                io.attach(serverHTTPS,{
                    path:'/socket.io',
                    transports: ['websocket']
                })
            }
            io.attach(serverHTTPS,{
                path:s.checkCorrectPathEnding(config.webPaths.home)+'socket.io',
                transports: ['websocket']
            })
            io.attach(serverHTTPS,{
                path:s.checkCorrectPathEnding(config.webPaths.admin)+'socket.io',
                transports: ['websocket']
            })
            io.attach(serverHTTPS,{
                path:s.checkCorrectPathEnding(config.webPaths.super)+'socket.io',
                transports: ['websocket']
            })
            if(sslInfo.autoRedirect === true){
                app.use(function(req, res, next) {
                  if(!req.secure) {
                      return res.redirect(['https://', req.hostname,":",sslInfo.port, req.url].join(''));
                  }
                  next();
                })
            }
            config.sslEnabled = true
        }catch(err){
            console.error(err)
        }
    }
    //start HTTP
    const onHttpRequestUpgradeExtensions = s.onHttpRequestUpgradeExtensions;
    var server = http.createServer(app);
    server.listen(config.port,config.bindip,function(){
        console.log(lang.Shinobi+' : Web Server Listening on '+config.port);
    });
    server.on('upgrade', function upgrade(request, socket, head) {
        const pathname = url.parse(request.url).pathname;
        if(typeof onHttpRequestUpgradeExtensions[pathname] === 'function'){
            onHttpRequestUpgradeExtensions[pathname](request, socket, head)
        } else if (pathname.indexOf('/socket.io') > -1) {
            return;
        } else {
            socket.destroy();
        }
    });
    if(config.webPaths.home !== '/'){
        io.attach(server,{
            path:'/socket.io',
            transports: ['websocket']
        })
    }
    io.attach(server,{
        path:s.checkCorrectPathEnding(config.webPaths.home)+'socket.io',
        transports: ['websocket']
    })
    io.attach(server,{
        path:s.checkCorrectPathEnding(config.webPaths.admin)+'socket.io',
        transports: ['websocket']
    })
    io.attach(server,{
        path:s.checkCorrectPathEnding(config.webPaths.super)+'socket.io',
        transports: ['websocket']
    })
    if(config.useUWebsocketJs === true){
        io.engine.ws = new (require('cws').Server)({
            noServer: true,
            perMessageDeflate: false
        })
    }
    return app
}
