review this file
const express = require('express');
const bodyParser = require('body-parser');
const methodOverride = require('method-override');
const http = require('http');
const _ = require('lodash');
const cors = require('cors');
const configurations = require("./config.json");
const options = {
    lockFileName: 'medics_lab_interface_server.lock',
    killTimeout: 10000,            // Set the timeout for waiting before terminating previous instance (in ms) if its already running.
    waitForExitTimeout: 20000,    // Set the timeout for waiting for the old process to exit (milliseconds)
    checkInterval: 500,           // Set the interval for checking the status of the other process (milliseconds)
    maxRetries: 3,                // Set the maximum number of retries for acquiring the lock
    defaultAnswer: 'yes'          // Set the default answer for user prompts
}
const LockManager = require('node-locksmith');
const lockManager = new LockManager(options);
// Initializes termination event handlers for graceful application shutdown.
lockManager.initializeTerminationHandlers();

// Import Logger and MongoDBService
const createLogger = require('../../services/Logger');
const connectToDatabase = require('../../services/MongoDBService');

// Create the application
const app = module.exports = express();

// Setup Logger
const logger = createLogger('MedicsLabInterfaceServer');

// Attach logger to the app
app.logger = logger;

/**
 * Initialize the Medics Lab Interface Server.
 * This function handles the setup of the application, including database connection, middleware,
 * error handling, and HTTP server creation.
 */
async function initializeApp() {
    try {
        // Check for lock
        await lockManager.checkLock();

        // Create the lock with a timeout and retries of specified intervals
        await lockManager.createLock(Infinity, 3);

        // Connect to MongoDB using MongoDBService
        await connectToDatabase(configurations.mongodbURL, logger);

        // Add middleware necessary for REST APIs
        app.use(cors());

        app.use(methodOverride('X-HTTP-Method-Override'));

        app.use(bodyParser.json({
            limit: '10mb'
        }));

        app.use(bodyParser.urlencoded({
            limit: '10mb',
            extended: true,
            parameterLimit: 10000
        }));

        // CORS Support
        app.use(function (req, res, next) {
            logger.info('Processing request:', req.url);
            if (req.body && Object.keys(req.body).length > 0) {
                logger.info('Request Body:', req.body);
            }

            res.header('Access-Control-Allow-Origin', '*');
            res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
            res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH');

            if (req.method === 'OPTIONS') {
                return res.status(200).json({});
            } else {
                next();
            }
        });

        // Error handling middleware
        app.use(function (err, req, res, next) {
            if (err.name === 'UnauthorizedError') {
                res.status(401);
                res.json({
                    "message": err.name + ": " + err.message
                });
            } else {
                logger.error(err.stack);
                res.status(500);
                res.json({
                    "message": "Internal Server Error"
                });
            }
        });

        // Load the models
        app.models = require('./models/index');

        // Load the Routes dynamically
        createRoutes();

        process.on('unhandledRejection', (error, promise) => {
            logger.error('Unhandled Promise Rejection:', error);
        });

        // Create an HTTP service.
        const httpPort = configurations.serverPort;
        logger.info(`HTTP server is listening on port: ${httpPort}`);
        http.createServer(app).listen(httpPort);

    } catch (error) {
        logger.error('Initialization error:', error);
        process.exit(1);
    }
}

const createRoutes = () => {
    const routes = require('./routes');
    _.each(routes, function (controller, route) {
        app.use(route, controller(app, route));
    });
};


// Call the async function to initialize the app
initializeApp();