text: require('dotenv').config()
  
  const express = require('express');
  const mongoose = require('mongoose');
  const methodOverride = require('method-override');
  const ejsMate = require('ejs-mate');
  const path = require('path');
  const session = require('express-session');
  const flash = require('connect-flash');
  const passport = require('passport');
  const LocalStrategy = require('passport-local');
  const helmet = require("helmet");
  const MongoStore = require('connect-mongo')(session);
  
  const ExpressError = require('./utils/ExpressError');
  const campgroundRoutes = require('./routes/campgrounds');
  const reviewRoutes = require('./routes/reviews');
  const userRoutes = require('./routes/users');
  const User = require('./models/user');
  const mongoSanitize = require('express-mongo-sanitize');
  
  
  const dbUrl = process.env.DB_URL;
  const localDB = "mongodb://localhost:27017/yelp-camp"
  
  const db = dbUrl || localDB
  mongoose.connect(`${db}`, {
      useNewUrlParser: true,
      useUnifiedTopology: true,
      useFindAndModify: false,
      useCreateIndex: true
  });
  
  
  const dbStatus = mongoose.connection;
  dbStatus.on('error', console.error.bind(console, 'connection error:'));
  dbStatus.once('open', function () {
      // connected!
      console.log("Database connected");
  });
  
  
  app = express();
  
  
  app.engine('ejs', ejsMate);
  
  
  app.set('views', path.join(__dirname, 'views'));
  app.set('view engine', 'ejs');
  
  
  app.use(express.urlencoded({ extended: true }));
  app.use(methodOverride('_method'));
  app.use(express.static(path.join(__dirname, 'public')));
  
  const secret = process.env.SESSION_SECRET; 
  app.use(session({
      secret,
      resave: false,
      saveUninitialized: true,
      cookie: {
          name: 'session',
          expires: Date.now() + 1000 * 60 * 60 * 24 * 7,
          maxAge: 1000 * 60 * 60 * 24 * 7,
          httpOnly: true,
          // secure: true Must be enabled during deployment for connection over HTTPS
      },
      store: new MongoStore({
          secret,
          url: db,
          touchAfter: 24 * 60 * 60
      })
  }));
  app.use(flash());
  app.use(passport.initialize());
  app.use(passport.session());
  app.use(mongoSanitize());
  app.use(helmet());
  
  passport.serializeUser(User.serializeUser());
  passport.deserializeUser(User.deserializeUser());
  passport.use(new LocalStrategy(User.authenticate()));
  
  const scriptSrcUrls = [
      "https://api.tiles.mapbox.com/",
      "https://api.mapbox.com/",
      "https://kit.fontawesome.com/",
      "https://cdnjs.cloudflare.com/",
      "https://cdn.jsdelivr.net",
  ];
  const styleSrcUrls = [
      "https://kit-free.fontawesome.com/",
      "https://api.mapbox.com/",
      "https://api.tiles.mapbox.com/",
      "https://fonts.googleapis.com/",
      "https://use.fontawesome.com/",
      "https://cdn.jsdelivr.net/npm/",
  ];
  const connectSrcUrls = [
      "https://api.mapbox.com/",
      "https://a.tiles.mapbox.com/",
      "https://b.tiles.mapbox.com/",
      "https://events.mapbox.com/",
  ];
  const fontSrcUrls = [];
  app.use(
      helmet.contentSecurityPolicy({
          directives: {
              defaultSrc: [],
              connectSrc: ["'self'", ...connectSrcUrls],
              scriptSrc: ["'unsafe-inline'", "'self'", ...scriptSrcUrls],
              styleSrc: ["'self'", "'unsafe-inline'", ...styleSrcUrls],
              workerSrc: ["'self'", "blob:"],
              objectSrc: [],
              imgSrc: [
                  "'self'",
                  "blob:",
                  "data:",
                  `https://res.cloudinary.com/${process.env.CLOUDINARY_NAME}/`, //SHOULD MATCH YOUR CLOUDINARY ACCOUNT! 
                  "https://images.unsplash.com/",
              ],
              fontSrc: ["'self'", ...fontSrcUrls],
          },
      })
  );
  
  
  app.use((req, res, next) => {
  
      // Deals with redirects after successfull login to previously requested URL
      // This occurs if the user tries to access resource unauthenticated. 
      if (!['/login', '/', '/logout', '/register'].includes(req.originalUrl)) {
          req.session.redirectUrl = req.originalUrl;
      }
  
      res.locals.currentUser = req.user;
      res.locals.success = req.flash('success');
      res.locals.error = req.flash('error');
  
      next();
  });
  
  // Routes
  app.use('/campgrounds', campgroundRoutes);
  app.use('/campgrounds/:id/reviews', reviewRoutes);
  app.use('/', userRoutes);
  
  
  
  // Home page
  app.get('/', (req, res) => {
  
      res.render('home');
  });
  
  
  // Displays a 404, if requested page is invalid 
  app.all('*', (req, res, next) => {
  
      next(new ExpressError("Page Not Found", 404));
  });
  
  
  // Error checking middleware
  app.use((err, req, res, next) => {
  
      const { statusCode = 500 } = err;
      if (!err.message) err.message = "Something Went Wrong";
      res.status(statusCode).render('error', { err });
  });
  
  
  // Serves either on host assigned port or default development port of 3000
  const port = process.env.PORT || 3000;
  app.listen(port, () => {
  
      console.log(`Serving on port ${port}.`);
  });
  
  