const express = require('express');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcrypt');

const app = express();
app.use(express.json());

const SECRET_KEY = 'TERRIBLESECRETKEYDOTWBEM'
const PORT = 3000

let users = [];

function authenticateToken(req, res, next) {
    const auth_header = req.headers['X-JWT-EXAMPLE-TOKEN'];
    const token = auth_header && auth_header.split(' ')[1];

    if (token == null) {
        res.status(401).json({
            'status': 'X-JWT-EXAMPLE-TOKEN not set'
        });
        
        return;
    }

    jwt.verify(token, SECRET_KEY, (err, user) => {
        if (err) {
            res.status(401).json({
                'status': 'Token not authorized'
            });
            return;
        }

        req.user = user;
        next();
    });
}

app.post('/register', async (req, res) => {
    try {
        users.push({
            username: req.body.username,
            password: bcrypt.hashSync(req.body.password, 10)
        });
        res.status(201).json({
            status: 'User Created'
        });
    } catch (error) {
        res.status(500).json({
            status: 'Internal server error',
            'error': error
        });
    }
});

app.post('/login', async (req, res) => {
    const user = users.find(user => user.username === req.body.username);

    if (user == null) {
        res.status(401).json({
            status: `User ${req.body.username} not authorized`
        });

        return;
    }

    try {
        if (bcrypt.compareSync(req.body.password, user.password)) {
            const access_token = jwt.sign({ username: user.username }, SECRET_KEY, { expiresIn: '1h'});
            res.status(200).json({
                status: 'OK',
                token: access_token
            });
        } else {
            res.status(401).json({
                'status': `User ${req.body.username} not authorized`
            });
        }
    } catch (error) {
        res.status(500).json({
            status: 'Internal server error',
            'error': error
        });
    }
});

app.get('/protected', authenticateToken, (req, res) => {
    res.status(200).json({
        status: 'OK',
        message: 'Protected resource access granted'
    });
})

app.listen(PORT, () => {
    console.log(`Server listening on port ${PORT}`)
});