text: // Copyright (c) Microsoft Corporation.
  // Licensed under the MIT License.
  
  const createError = require('http-errors');
  const express = require('express');
  const path = require('path');
  const cookieParser = require('cookie-parser');
  const logger = require('morgan');
  const session = require('express-session');
  const flash = require('connect-flash');
  const msal = require('@azure/msal-node');
  require('dotenv').config();
  
  const indexRouter = require('./routes/index');
  const usersRouter = require('./routes/users');
  const authRouter = require('./routes/auth');
  const calendarRouter = require('./routes/calendar');
  
  const app = express();
  
  // <MsalInitSnippet>
  // In-memory storage of logged-in users
  // For demo purposes only, production apps should store
  // this in a reliable storage
  app.locals.users = {};
  
  // MSAL config
  const msalConfig = {
    auth: {
      clientId: process.env.OAUTH_CLIENT_ID,
      authority: process.env.OAUTH_AUTHORITY,
      clientSecret: process.env.OAUTH_CLIENT_SECRET
    },
    system: {
      loggerOptions: {
        loggerCallback(loglevel, message, containsPii) {
          console.log(message);
        },
        piiLoggingEnabled: false,
        logLevel: msal.LogLevel.Verbose,
      }
    }
  };
  
  // Create msal application object
  app.locals.msalClient = new msal.ConfidentialClientApplication(msalConfig);
  // </MsalInitSnippet>
  
  // <SessionSnippet>
  // Session middleware
  // NOTE: Uses default in-memory session store, which is not
  // suitable for production
  app.use(session({
    secret: 'your_secret_value_here',
    resave: false,
    saveUninitialized: false,
    unset: 'destroy'
  }));
  
  // Flash middleware
  app.use(flash());
  
  // Set up local vars for template layout
  app.use(function(req, res, next) {
    // Read any flashed errors and save
    // in the response locals
    res.locals.error = req.flash('error_msg');
  
    // Check for simple error string and
    // convert to layout's expected format
    var errs = req.flash('error');
    for (var i in errs){
      res.locals.error.push({message: 'An error occurred', debug: errs[i]});
    }
  
    // Check for an authenticated user and load
    // into response locals
    if (req.session.userId) {
      res.locals.user = app.locals.users[req.session.userId];
    }
  
    next();
  });
  // </SessionSnippet>
  
  // view engine setup
  app.set('views', path.join(__dirname, 'views'));
  app.set('view engine', 'hbs');
  
  // <FormatDateSnippet>
  var hbs = require('hbs');
  var parseISO = require('date-fns/parseISO');
  var formatDate = require('date-fns/format');
  // Helper to format date/time sent by Graph
  hbs.registerHelper('eventDateTime', function(dateTime) {
    const date = parseISO(dateTime);
    return formatDate(date, 'M/d/yy h:mm a');
  });
  // </FormatDateSnippet>
  
  app.use(logger('dev'));
  app.use(express.json());
  app.use(express.urlencoded({ extended: false }));
  app.use(cookieParser());
  app.use(express.static(path.join(__dirname, 'public')));
  
  app.use('/', indexRouter);
  app.use('/auth', authRouter);
  app.use('/calendar', calendarRouter);
  app.use('/users', usersRouter);
  
  // catch 404 and forward to error handler
  app.use(function(req, res, next) {
    next(createError(404));
  });
  
  // error handler
  app.use(function(err, req, res, next) {
    // set locals, only providing error in development
    res.locals.message = err.message;
    res.locals.error = req.app.get('env') === 'development' ? err : {};
  
    // render the error page
    res.status(err.status || 500);
    res.render('error');
  });
  
  module.exports = app;
  