const express = require('express');
const bodyParser = require('body-parser');
const crypto = require('crypto');
const app = express();

const fs = require('fs');

app.use(bodyParser.json());
app.set('view engine', 'ejs');
app.use(express.static('static'));

app.get('/', (req, res) => {
    res.setHeader('X-Powered-By', 'got-hacked.rip magic software');
    res.render('index.ejs');
});

app.post('/write', (req, res) => {
    res.setHeader('X-Powered-By', 'got-hacked.rip magic software');
    let filename = crypto.randomBytes(16).toString('hex');
    let datainput = req.body;
    if(datainput.text == undefined || datainput.text == "") return res.send('Error: Text is invalid').status(403);
    if(fs.existsSync(__dirname+'/bin/'+filename+'.json')) {
        console.log(`EYO WHAT THE HELL HAPPENED, WE JUST GOT THE MOST STUPID OCCURENCE EVER - RANDOMLY GENERATED ID OCCURS AGAIN ${Date.now()} ${filename}`);
        res.send('WHAT? Internal error - randomly generated ID already exists? Try again.').status(500);
        return;
    }

    if(typeof datainput.status != "boolean") {
        res.status(500).render('error',{error:'STATUS IS NOT BOOLEAN'});
        return;
    }

    // Encryption
    let key = "";
    let iv = [];

    let text = datainput.text;

    if(datainput.status == true) {
        key = crypto.randomBytes(32);
        iv = crypto.randomBytes(16);
        let cipher = crypto.createCipheriv('aes-256-gcm', key, iv);

        let updated = cipher.update(datainput.text);

        text = updated.toJSON().data;
    }

    let data = {
        name: datainput.name == undefined ? '' : datainput.name,
        text: text,
        status: datainput.status == undefined ? false : datainput.status
    }

    fs.writeFile(__dirname+'/bin/'+filename+'.json', JSON.stringify(data), (err) => {
        if (err) {
            console.log(err);
            res.render('error',{error:'Major internal error has happened, error written in console.'}).status(500);
        } else {
            console.log(filename, key, iv);
            res.send({filename: filename, key: key.toString('hex'), iv: iv.toString('hex')}).status(200);
        }
    });
});

app.get('/new', (req, res) => {
    res.setHeader('X-Powered-By', 'got-hacked.rip magic software');
    res.render('new.ejs');
});

app.get('/paste/:id', (req, res) => {
    res.setHeader('X-Powered-By', 'got-hacked.rip magic software');
    let fs = require('fs');
    let filename = req.params.id;
    if(!fs.existsSync(__dirname+'/bin/'+filename+'.json')) return res.status(404).render('error',{error:'Error: Paste not found'});
    let data = JSON.parse(fs.readFileSync(__dirname+'/bin/'+filename+'.json', 'utf8'));

    let text = data.text;

    if(data.status == true) {
        // We need to decrypt the paste and send it using the ?e= argument
        if(req.query?.e == undefined || req.query?.iv == undefined) {
            res.status(500).render('error',{error:"Error - tried to read encrypted paste without required arguments!"});
            return;
        }
        let key = req.query.e;
        let iv = req.query.iv;

        // attempt to decrypt the paste using crypto

        try {
            let decipher = crypto.createDecipheriv('aes-256-gcm', Buffer.from(key, 'hex'), Buffer.from(iv, 'hex'));
            let updated = decipher.update(Buffer.from(data.text));
            text = updated;
        } catch(e) {
            res.status(500).render('error',{error:"An internal error occured, please read console if you are a system administrator! If you are just a regular user, DM me on Discord: ♫ The Red ♫#7227 you may also report the issue on my personal website feedback box (thered.sh)"});
            console.log(e);
            return;
        }
    }

    res.render('paste.ejs', {
        name: data.name,
        text: text,
        status: data.public ? "Public" : (data.status ? "Link Encryption Enabled" : "Link Encryption Disabled"),
        id: filename
    });
});

app.get('/admin', (req, res) => {
    res.setHeader('X-Powered-By', 'got-hacked.rip magic software');
    res.render('error',{error:"Page not complete yet. An average user is not meant to access this anyway, however, lol"});
});

app.get('/api', (req, res) => {
    res.setHeader('X-Powered-By', 'got-hacked.rip magic software');
    res.render('error',{error:"Unfortunately, there is no official API as of right now. This is planned to release soon, however."})
});

// app.get('/newdesign', (req, res) => {
//     res.render('newdesign.ejs');
// });

app.get('*', (req, res) => {
    res.setHeader('X-Powered-By', 'got-hacked.rip magic software');
    res.status(404).render('error',{error:"The page you were trying to access couldn't be found, or some uncaught internal error has happened. However, this error is marked as a 404."})
});

app.listen(30180);