"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EVENT_ASSET_WRITE_END = exports.EVENT_ASSET_WRITE_START = exports.EVENT_ASSET_READ_END = exports.EVENT_ASSET_READ_START = exports.EVENT_WRITE_END = exports.EVENT_WRITE_START = exports.EVENT_READ_END = exports.EVENT_READ_START = void 0;
const express_1 = require("express");
const formidable = require("formidable");
const project_1 = require("../project");
const express_2 = require("../express");
const events_1 = require("../events");
exports.EVENT_READ_START = 'EVENT_READ_START';
exports.EVENT_READ_END = 'EVENT_READ_END';
exports.EVENT_WRITE_START = 'EVENT_WRITE_START';
exports.EVENT_WRITE_END = 'EVENT_WRITE_END';
exports.EVENT_ASSET_READ_START = 'EVENT_ASSET_READ_START';
exports.EVENT_ASSET_READ_END = 'EVENT_ASSET_READ_END';
exports.EVENT_ASSET_WRITE_START = 'EVENT_ASSET_WRITE_START';
exports.EVENT_ASSET_WRITE_END = 'EVENT_ASSET_WRITE_END';
async function default_1(config, opts = {}) {
    const options = {
        ...opts
    };
    config.on(events_1.EVENT_STARTUP_START, ({ app }) => {
        const router = (0, express_1.Router)();
        router.get('/website', readWebsite);
        router.post('/website', writeWebsite);
        router.get(/\/assets\/(.*)/, readAsset);
        router.post('/assets', writeAsset);
        (0, project_1.initProjects)()
            .catch(err => {
            console.error('Error: could not create folder ', err);
        });
        app.use(express_2.noCache, router);
    });
    async function readWebsite(req, res) {
        const projectId = req.body.projectId;
        config.emit(exports.EVENT_READ_START, { req, projectId });
        try {
            const data = await (0, project_1.readProjectData)(projectId);
            config.emit(exports.EVENT_READ_END, { req, res, data, projectId });
            res
                .type('application/json')
                .send(data);
        }
        catch (err) {
            if (err.code === 'ENOENT') {
                res.json({});
            }
            else {
                console.error('Read file error', err);
                res.status(400).json({ message: 'Read file error: ' + err.message, code: err.code });
            }
        }
    }
    function fromBody(body) {
        try {
            return [{
                    assets: body.assets,
                    pages: body.pages,
                    files: body.files,
                    styles: body.styles,
                    settings: body.settings,
                    publication: body.publication,
                    name: body.name,
                    fonts: body.fonts,
                    symbols: body.symbols,
                }, null];
        }
        catch (err) {
            console.error('Could not parse body data', body, err);
            return [null, err];
        }
    }
    async function writeWebsite(req, res) {
        const projectId = req.query.projectId;
        await (0, project_1.initProject)(projectId);
        const [data, err] = fromBody(req.body);
        if (err) {
            res.status(400).json({ message: 'Error writing data file, could not parse the provided body: ' + err.message, code: err.code });
            return;
        }
        config.emit(exports.EVENT_WRITE_START, { req, projectId, data });
        try {
            await (0, project_1.writeProjectData)(projectId, data);
        }
        catch (err) {
            console.error('Error writing data file', err);
            res.status(500).json({ message: 'Error writing data file: ' + err.message, code: err.code });
            return;
        }
        config.emit(exports.EVENT_WRITE_END, { res, req, projectId, data });
        res.json({
            message: 'OK',
        });
    }
    async function readAsset(req, res) {
        const projectId = req.query.projectId;
        const fileName = req.params[0];
        const uploadDir = await (0, project_1.assetsDir)(projectId);
        config.emit(exports.EVENT_ASSET_READ_START, { req, projectId, fileName, uploadDir });
        res.sendFile(`${uploadDir}/${fileName}`);
        config.emit(exports.EVENT_ASSET_READ_END, { req, projectId, fileName, uploadDir });
    }
    async function writeAsset(req, res) {
        const projectId = req.query.projectId;
        const uploadDir = await (0, project_1.assetsDir)(projectId);
        (0, project_1.initProject)(projectId);
        const form = formidable({
            uploadDir,
            filename: (name, ext, part, _form) => `${name}${ext}`,
            multiples: true,
            keepExtensions: true,
        });
        form.parse(req, async (err, fields, files) => {
            if (err) {
                console.error('Error parsing upload data', err);
                res
                    .status(400)
                    .json({ message: 'Error parsing upload data: ' + err.message, code: err.code });
                return;
            }
            Promise.all([].concat(files['files[]'])
                .map(file => {
                const { originalFilename, filepath } = file;
                return (0, project_1.assetUrl)(projectId, originalFilename);
            }))
                .then(data => {
                config.emit(exports.EVENT_ASSET_WRITE_START, { req, projectId, uploadDir, form, data });
                res.json({ data });
                config.emit(exports.EVENT_ASSET_WRITE_END, { res, req, projectId, uploadDir, form, data });
            });
        });
    }
}
exports.default = default_1;
