'use strict'

import dotenv from 'dotenv'
const env = dotenv.config()

import { promises as fs } from 'fs'
import http from 'http'
import express from 'express'
import session from 'express-session'
import cookieParser  from'cookie-parser'
import { Server } from'socket.io'
import path from 'path'
import passport from 'passport'
import { Strategy as LocalStrategy } from 'passport-local'
//import { createRequire } from 'module';
//const require = createRequire(import.meta.url);
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

//const redis = require('redis-url').connect()
//const RedisStore = require('connect-redis')(session)
/*const passportSocketIo = require('passport.socketio')*/

import indexRouter from './routes/index.js'

import cors from 'cors'

import JamiRestApi from './routes/jami.js'
import JamiDaemon from './JamiDaemon.js'
// import { sentrySetUp } from './sentry.js'

const configPath = 'jamiServerConfig.json'

//const sessionStore = new RedisStore({ client: redis })
const sessionStore = new session.MemoryStore()

const loadConfig = async (filePath) => {
    const config = {users: {}, authMethods: []}
    try {
        return Object.assign(config, JSON.parse(await fs.readFile(filePath)))
    } catch(e) {
        console.log(e)
        return config
    }
}

const saveConfig = (filePath, config) => {
    return fs.writeFile(filePath, JSON.stringify(config))
}

/*
Share sessions between Passport.js and Socket.io
*/

function logSuccess() {
    console.log('passportSocketIo authorized user with Success 😁')
}

function logFail() {
    console.log('passportSocketIo failed to authorized user 👺')
}

/*

tempAccounts holds users accounts while tempting to authenticate them on Jams.
connectedUsers  holds users accounts after they got authenticated by Jams.

Users should be removed from connectedUsers when receiving a disconnect
web socket call

*/
const tempAccounts = {}
const connectedUsers = {}

const createServer = async (appConfig) => {
    const app = express()
    console.log(`Loading server for ${app.get('env')} with config:`)
    console.log(appConfig)
    const development = app.get('env') === 'development'

    var corsOptions = {
        origin: 'http://127.0.0.1:3000'
    }

    if (development) {
        const [ webpack, webpackDev, webpackHot, webpackConfig ] = await Promise.all([
            import('webpack'),
            import('webpack-dev-middleware'),
            import('webpack-hot-middleware'),
            import('./client/webpack.config.js')
        ])
        const compiler = webpack.default(webpackConfig.default)
        app.use(webpackDev.default(compiler, {
            publicPath: webpackConfig.default.output.publicPath
        }))
        app.use(webpackHot.default(compiler))
    }

    /*
        Configuation for Passeport Js
    */
    app.disable('x-powered-by')

    const sessionMiddleware = session({
        store: sessionStore,
        resave: false,
        saveUninitialized: true,
        cookie: {
            secure: false,//!development,
            maxAge: 2419200000
        },
        secret: process.env.SECRET_KEY_BASE
    })

    app.use(sessionMiddleware)
    app.use(passport.initialize())
    app.use(passport.session())
    // app.use(app.router)
    app.use(cors(corsOptions))

    const jami = new JamiDaemon((account, conversation, message) => {
        console.log('JamiDaemon onMessage')

        if (conversation.listeners) {
            Object.values(conversation.listeners).forEach(listener => {
                listener.socket.emit('newMessage', message)
            })
        }
    })
    const apiRouter = new JamiRestApi(jami).getRouter()

    /*
    io.use(passportSocketIo.authorize({
        key: 'connect.sid',
        secret: process.env.SECRET_KEY_BASE,
        store: sessionStore,
        passport: passport,
        cookieParser: cookieParser,
        //success: logSuccess(),
        // fail: logFail(),
    }))
    */

    const isSetupComplete = () => {
        return 'admin' in appConfig.users
    }

    const accountFilter = filter => {
        if (typeof filter === 'string') {
            if (filter === '*')
                return undefined
            else
                return account => account.getId() === filter
        } else if (Array.isArray(filter)) {
            return account => filter.includes(account.getId())
        } else {
            throw new Error('Invalid account filter string')
        }
    }

    const user = (id, config) => {
        return {
            id,
            config,
            username: config.username || id,
            accountFilter: accountFilter(config.accounts)
        }
    }

    passport.serializeUser((user, done) => {
        connectedUsers[user.id] = user.config
        console.log('=============================SerializeUser called ' + user.id)
        console.log(user)
        done(null, user.id)
    })

    const deserializeUser = (id, done) => {
        console.log('=============================DeserializeUser called on: ' + id)
        const userConfig = connectedUsers[id]
        console.log(userConfig)
        if (userConfig) {
            done(null, user(id, userConfig))
        } else
            done(404, null)
    }
    passport.deserializeUser(deserializeUser)

    const jamsStrategy = new LocalStrategy(
        (username, password, done) => {
            const accountId = jami.addAccount({
                'managerUri': 'https://jams.savoirfairelinux.com',
                'managerUsername': username,
                'archivePassword': password
            })
            const id = `jams_${username}`
            const userConfig = { username, type: 'jams', accounts: accountId }
            const newUser = user(id, userConfig)
            console.log('AccountId: ' + accountId)
            tempAccounts[accountId] = { done, newUser }

        }
    )
    jamsStrategy.name = 'jams'

    const localStrategy = new LocalStrategy(
        (username, password, done) => {
            console.log('localStrategy: ' + username + ' ' + password)

            const id = username
            const userConfig = appConfig.users[username]
            if (!userConfig) {
                return done(null, false, { message: 'Incorrect username.' })
            }
            if (userConfig.password !== password) {
                return done(null, false, { message: 'Incorrect password.' })
            }
            userConfig.type = 'local'

            done(null, user(id, userConfig))
        }
    )

    passport.use(jamsStrategy)
    passport.use(localStrategy)

    const secured = (req, res, next) => {
        if (req.user) {
            return next()
        }
        res.status(401).end()
    }
    const securedRedirect = (req, res, next) => {
        if (req.user && req.user.accountId) {
            return next()
        }
        req.session.returnTo = req.originalUrl
        res.redirect('/login')
    }

    app.use(express.json())
    app.post('/setup', (req, res) => {
        if (isSetupComplete()) {
            return res.status(404).end()
        }
        if (!req.body.password) {
            return res.status(400).end()
        }
        console.log(req.body)
        appConfig.users.admin = {
            'accounts': '*',
            password: req.body.password
        }
        res.status(200).end()
        saveConfig(configPath, appConfig)
    })
    app.post('/auth/jams', passport.authenticate('jams'), (req, res) => {
        res.json({ loggedin: true })
    })
    app.post('/auth/local', passport.authenticate('local'), (req, res) => {
        res.json({ loggedin: true, user: req.user.id })
    })

    const getState = req => {
        if (req.user) {
            return { loggedin: true, username: req.user.username, type: req.user.type }
        } else if (isSetupComplete()) {
            return {}
        } else {
            return { setupComplete: false }
        }
    }

    // sentrySetUp(app);

    app.get('/auth', (req, res) => {
        const state = getState(req)
        if (req.user) {
            res.json(state)
        } else {
            res.status(401).json(state)
        }
    })

    app.use('/api', secured, apiRouter)

    app.use('/', indexRouter)

    /* GET React App */

    app.use(express.static(path.join(__dirname, 'client', 'dist')))

    app.use((req, res, next) => {
        res.render(path.join(__dirname, 'client', 'dist', 'index.ejs'), {
            initdata: JSON.stringify(getState(req))
        })
    })


    const server = http.Server(app)

    const io = new Server(server, { cors: corsOptions })
    const wrap = middleware => (socket, next) => middleware(socket.request, {}, next)
    io.use(wrap(sessionMiddleware))
    io.use(wrap(passport.initialize()))
    io.use(wrap(passport.session()))
    io.use((socket, next) => {
        if (socket.request.user) {
            next()
        } else {
            next(new Error('unauthorized'))
        }
    })
    io.on('connect', (socket) => {
        console.log(`new connection ${socket.id}`)
        const session = socket.request.session
        console.log(`saving sid ${socket.id} in session ${session.id}`)
        session.socketId = socket.id
        session.save()

        socket.on('conversation', (data) => {
            console.log('io conversation')
            console.log(data)
            if (session.conversation) {
                console.log(`disconnect from old conversation ${session.conversation.conversationId}`)
                const conversation = jami.getConversation(session.conversation.accountId, session.conversation.conversationId)
                delete conversation.listeners[socket.id]
            }
            session.conversation = { accountId: data.accountId, conversationId: data.conversationId }
            const conversation = jami.getConversation(data.accountId, data.conversationId)
            if (!conversation.listeners)
                conversation.listeners = {}
            conversation.listeners[socket.id] = {
                socket, session
            }
            session.save()
        })
    })

    return server
}

loadConfig(configPath)
    .then(createServer)
    .then(server => {
        server.listen(3000)
    })
