/*
 * Copyright (C) 2024-present Puter Technologies Inc.
 * 
 * This file is part of Puter.
 * 
 * Puter is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

const configurable_auth = require("../middleware/configurable_auth");
const { Endpoint } = require("../util/expressutil");
const BaseService = require("./BaseService");

class WispService extends BaseService {
    ['__on_install.routes'] (_, { app }) {
        const r_wisp = (() => {
            const require = this.require;
            const express = require('express');
            return express.Router();
        })();

        app.use('/wisp', r_wisp);

        Endpoint({
            route: '/relay-token/create',
            methods: ['POST'],
            mw: [configurable_auth()],
            handler: async (req, res) => {
                const svc_token = this.services.get('token');
                const actor = req.actor;
                const token = svc_token.sign('wisp', {
                    $: 'token:wisp',
                    $v: '0.0.0',
                    user_uid: actor.type.user.uuid,
                }, {
                    expiresIn: '1d',
                });
                res.json({ token });
            }
        }).attach(r_wisp);

        Endpoint({
            route: '/relay-token/verify',
            methods: ['POST'],
            handler: async (req, res) => {
                const svc_token = this.services.get('token');
                const svc_apiError = this.services.get('api-error');
                const svc_event = this.services.get('event');

                const decoded = (() => {
                    try {
                        const decoded = svc_token.verify('wisp', req.body.token);
                        if ( decoded.$ !== 'token:wisp' ) {
                            throw svc_apiError.create('invalid_token');
                        }
                        return decoded;
                    } catch (e) {
                        throw svc_apiError.create('forbidden');
                    }
                })();
                
                const svc_getUser = this.services.get('get-user');

                const event = {
                    allow: true,
                    policy: {},
                    user: await svc_getUser.get_user({
                        uuid: decoded.user_uid,
                    }),
                };
                await svc_event.emit('wisp.get-policy', event);
                if ( ! event.allow ) {
                    this.log.noticeme('here')
                    throw svc_apiError.create('forbidden');
                }

                res.json(event.policy);
            }
        }).attach(r_wisp);
    }
}

module.exports = {
    WispService,
};
