require("dotenv").config();

const express = require("express");
const bodyParser = require("body-parser");
const path = require("path");
const log4js = require("log4js");

const timeInitialise = require("./middleware/initialise");
const cronRoutes = require("./routes/cron");
const userRoutes = require("./routes/user");
const userPausesRoutes = require("./routes/pause");
const userPaymentsRoutes = require("./routes/payment");
const questionnairesRoutes = require("./routes/questionnaire");
const questionsRoutes = require("./routes/question");
const choicesRoutes = require("./routes/choice");
const illustrationRoutes = require("./routes/illustration");
const linkRoutes = require("./routes/link");
const tagRoutes = require("./routes/tag");

const config = require("./config/main");
const confLog4js=require("./config/log4js");
const txt = require("./lang/"+config.adminLang+"/general");
const tool = require("./tools/main");

const app = express();

app.use(timeInitialise);
app.use((req, res, next) =>
{
    res.setHeader("Access-Control-Allow-Origin", "*");
    res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content, Accept, Content-Type, Authorization");
    res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
    next();
});

app.use(express.static(path.join(__dirname, "front/public/img")));// permet affichage images côté API, notamment favicon.
app.use(bodyParser.json());
app.use("/api/user", userRoutes);
app.use("/api/pause", userPausesRoutes);
app.use("/api/payment", userPaymentsRoutes);
app.use("/api/questionnaire", questionnairesRoutes);
app.use("/api/questionnaire", tagRoutes);
app.use("/api/question", questionsRoutes);
app.use("/api/question", choicesRoutes);
app.use("/api/illustration", illustrationRoutes);
app.use("/api/link", linkRoutes);
app.use("/api/cron", cronRoutes);

// Évalue de la durée de la réponse (!= durée script, car fonctions asynchrones continuent). Mettre next() après réponse des contrôleurs... à contrôler !
// Capture aussi les url inconnues en retournant une erreur 404.
// Je peux aussi recevoir des messages à afficher dans les logs venant des "cron".
app.use((req, res, next) => 
{
    try
    {
        if(res.headersSent)
        {
            log4js.configure(confLog4js);// ici, car pas pris en compte si je le fais avant le middleware (?).
            const myLogs = log4js.getLogger(config.env);
            let timeEnd=Date.now(), maxTime=config.responseTimingAlertInSeconde;
            if(req.url.startsWith("/api/cron"))
                maxTime=config.cronTimingAlertInSeconde;
            const mapMessage =
            {
                SCRIPT_TIMING: timeEnd-req.timeBegin,
                SCRIPT_URL: req.url
            };
            if(config.env === "development")
            {
                myLogs.info(tool.replaceAll(txt.scriptTimingInfo, mapMessage));
                if(res.alerte)
                    myLogs.warn(res.alerte);
            }
            else if((timeEnd-req.timeBegin) > maxTime*1000)
            {
                myLogs.warn(tool.replaceAll(txt.scriptTimingAlert, mapMessage));
                if(res.message)
                    myLogs.info(res.message);
            } 
            next();
        }
        else
        {
            const err = new Error(txt.badUrl);
            err.status=404;
            next(err);
        }
    }
    catch(e)
    {
        next(e);
    }
});

// Capture et traitement des erreurs
app.use((err, req, res, next) => 
{
    const status = (err.status) ? err.status : 500;
    if(!res.headersSent)
        res.status(status).json({ errors: txt.serverError });
    log4js.configure(confLog4js);// même remarque que + haut
    const myLogs = log4js.getLogger(config.env);
    myLogs.error(txt.serverErrorAdmin, { message : err.message, url: req.url });
});
log4js.shutdown();

module.exports = app;