/** 
 * @file Initialise et configure le serveur Express sur lequel tourne le back.
 * 
 * La configuration inclut tout le _middleware_ définissant les API et les services
 * nécessaire utilisés, comme `express-session`, GraphiQL, GraphQL Voyager.
 * @author manifold
*/
import express from 'express';
import schema from './graphql/schema';
import { express as graphqlVoyager } from 'graphql-voyager/middleware';
import graphqlHTTP from 'express-graphql'; // new name of 'graphql-server-express'. cf npmjs.com
import flash from 'connect-flash';
import { ensureLoggedIn } from 'connect-ensure-login';
import './auth';
import passport from 'passport';
import session from 'express-session';
import bodyParser from 'body-parser';
import favicon from 'serve-favicon';
import morgan from 'morgan';
import path from 'path';
import fs from 'fs';
import cors from 'cors';

const server = express();

// Parse incoming HTTP request bodies, available under the req.body property
// cf www.npmjs.com/package/body-parser
server.use(bodyParser.json()); //parses bodies of media type "application/json"
server.use(bodyParser.urlencoded({ //parses bodies of media type "application/x-www-form-urlencoded"
    extended: true //use qs library (quoi que ca veuille dire o.O)
}));

const configPath = path.resolve('./', 'ldap_config.json');
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));

// Définit les paramètres de stockage des sessions.
server.use(session({
    secret: config.sessionSecret,
    resave: true,
    saveUninitialized: false
}));
server.use(passport.initialize());
server.use(passport.session());


/* fin de Configuration de l'authentification */

// cache le fait que l'application tourne sous Express dans le header HTTP.
server.disable('x-powered-by');

// setting up view engine for pug
console.log("Running at",__dirname);
let viewpath = path.resolve(__dirname,'views');
server.set('views', viewpath);
server.set('view engine', 'pug');

// favicon: capital sigma symbol
server.use(favicon(path.resolve('./','assets','favicon.ico')));

// specifies path to static assets
server.use('/assets',express.static(path.resolve('./','assets')));

// Morgan is middleware for logging requests
server.use(morgan('dev'));

const defaultUser = require('./../ldap_connexion_config.json');

// Options de configuration pour le _middleware_ `cors`.
// CORS = Cross Origin Resource Sharing
const corsOptions = {
    origin: 'http://localhost:8888', // Configures the Access-Control-Allow-Origin CORS header. i.e. specifies that sigma-back wants to make resources accessible to this site (and this site only)
    credentials: true // Configures the Access-Control-Allow-Credentials CORS header. i.e. allows cookies to be included on cross-origin requests
};
server.use(cors(corsOptions));

server.use('/graphql', 
    bodyParser.json(), // parse incoming HTTP request (req) as a JSON
    graphqlHTTP(async (req, res, params) => {
        // vary the options *on a per-request basis*
        let uid;
        let password;

        if(req.isAuthenticated()) {
            try {
                uid = req.user.uid;
                password = "mythe";
            } catch (err) {
                console.log("Error: req is authenticated, but pb when trying to extract uid from req.user. Probably user was either not serialized or not deserialized properly");
                console.log(err);
            }
        } else {
            // FOR DEVELOPMENT ONLY. for production, replace with a "publicUser" or "notLoggedInUser" or something.
            uid = defaultUser.dn.split("=")[1].split(",")[0];
            password = defaultUser.passwd;
        }
        // console.log("Accessing GraphQL as: ",uid);

        return {
            schema: schema,
            graphiql: true, // gives access to graphiql if request is detected to be from browser (je crois)
            context: { user: { uid: uid, password: password } } // accessible in every single resolver as the third argument
        };
    })
);

// GraphQL voyager affiche une représentation sous forme de graphe du schema GraphQL
server.use('/voyager',
    /*ensureLoggedIn('/login'),*/
    graphqlVoyager({ endpointUrl: '/graphql' })
);

// connect-flash is middleware for flashing messages
// used in sigma-back's admin interface (admin_view)
server.use(flash());

export default server;