// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

// module dependencies
const path = require('path');
const morgan = require('morgan');
const express = require('express');
const compress = require('compression');
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const appRoot = require('app-root-path');
const favicon = require('serve-favicon');
const config = require('./index');
const logger = require('./logger');

const app = express();

app.use(compress());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(cookieParser());

// setup the logger for requests
app.use(morgan('dev', { stream: logger.stream }));

// setup favicon
app.use(favicon(path.join(appRoot.path, 'dist', 'favicon.ico')));

// setup the root path
const oneMonth = 3600 * 24 * 30 * 1000;

app.use(
  '/assets',
  express.static(path.join(appRoot.path, 'dist/assets'), { maxAge: oneMonth }),
);
app.use(
  '/styles',
  express.static(path.join(appRoot.path, 'dist/styles'), { maxAge: oneMonth }),
);
app.use(
  '/scripts',
  express.static(path.join(appRoot.path, 'dist/scripts'), { maxAge: oneMonth }),
);
app.use(express.static(path.join(appRoot.path, 'dist')));

// catch 404 and forward to error handler
app.use((req, res, next) => {
  const err = new Error('Page not found');
  err.status = 404;
  next(err);
});

// error handler
app.use((err, req, res, next) => {
  logger.warn('%s', err.stack);
  res.status(err.status || 500).json({
    message: err.message,
    error: config.env === 'development' ? err.stack : {},
  });
});

// module exports
module.exports = app;
