var express = require('express'); var app = express(); const bodyParser = require('body-parser'); app.use(bodyParser.urlencoded({ extended: false})); app.use(bodyParser.json()); /* Flight: "name" "take-off time" "priority" "status" //*/ function uuidv4() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); } function Flight( name, boardId, unitId ) { this.assignedAltitude = 0; this.assignedSpeed = 0; this.id = uuidv4(); this.boardId = boardId; this.name = name; this.status = "unknown"; this.takeoffTime = -1; this.unitId = parseInt( unitId ); } Flight.prototype.getData = function() { return { "assignedAltitude" : this.assignedAltitude, "assignedSpeed" : this.assignedSpeed, "id" : this.id, "boardId" : this.boardId, "name" : this.name, "status" : this.status, "takeoffTime" : this.takeoffTime, "unitId" : this.unitId }; } Flight.prototype.setAssignedAltitude = function( assignedAltitude ) { if ( isNaN( assignedAltitude ) ) { return "Altitude must be a number" } this.assignedAltitude = parseInt( assignedAltitude ); return true; } Flight.prototype.setAssignedSpeed = function( assignedSpeed ) { if ( isNaN( assignedSpeed ) ) { return "Speed must be a number" } this.assignedSpeed = parseInt( assignedSpeed ); return true; } Flight.prototype.setOrder = function( order ) { this.order = order; return true; } Flight.prototype.setStatus = function( status ) { if ( [ "unknown", "checkedin", "readytotaxi", "clearedtotaxi", "halted", "terminated" ].indexOf( status ) < 0 ) { return "Invalid status"; } this.status = status; return true; } Flight.prototype.setTakeoffTime = function( takeoffTime ) { if ( takeoffTime === "" || takeoffTime === -1 ) { this.takeoffTime = -1; } if ( isNaN( takeoffTime ) ) { return "Invalid takeoff time" } this.takeoffTime = parseInt( takeoffTime ); return true; } function ATCDataHandler( data ) { this.data = data; } ATCDataHandler.prototype.addFlight = function( flight ) { if ( flight instanceof Flight === false ) { throw new Error( "Given flight is not an instance of Flight" ); } this.data.flights[ flight.id ] = flight; } ATCDataHandler.prototype.deleteFlight = function( flightId ) { delete this.data.flights[ flightId ]; } ATCDataHandler.prototype.getFlight = function( flightId ) { return this.data.flights[ flightId ] || false; } ATCDataHandler.prototype.getFlights = function() { return this.data.flights; } const dataHandler = new ATCDataHandler( { "flights": {} } ); /**************************************************************************************************************/ // Endpoints /**************************************************************************************************************/ app.get( "/flight", ( req, res ) => { let flights = Object.values( dataHandler.getFlights() ); if ( flights && req.query.boardId ) { flights = flights.reduce( ( acc, flight ) => { if ( flight.boardId === req.query.boardId ) { acc[ flight.id ] = flight; } return acc; }, {} ); } res.json( flights ); }); app.patch( "/flight/:flightId", ( req, res ) => { const flightId = req.params.flightId; const flight = dataHandler.getFlight( flightId ); if ( !flight ) { res.status( 400 ).send( `Unrecognised flight ID (given: "${req.params.flightId}")` ); } if ( req.body.hasOwnProperty( "assignedAltitude" ) ) { const altitudeChangeSuccess = flight.setAssignedAltitude( req.body.assignedAltitude ); if ( altitudeChangeSuccess !== true ) { res.status( 400 ).send( altitudeChangeSuccess ); } } if ( req.body.hasOwnProperty( "assignedSpeed" ) ) { const speedChangeSuccess = flight.setAssignedSpeed( req.body.assignedSpeed ); if ( speedChangeSuccess !== true ) { res.status( 400 ).send( speedChangeSuccess ); } } if ( req.body.status ) { const statusChangeSuccess = flight.setStatus( req.body.status ); if ( statusChangeSuccess !== true ) { res.status( 400 ).send( statusChangeSuccess ); } } if ( req.body.hasOwnProperty( "takeoffTime" ) ) { const takeoffChangeSuccess = flight.setTakeoffTime( req.body.takeoffTime ); if ( takeoffChangeSuccess !== true ) { res.status( 400 ).send( takeoffChangeSuccess ); } } res.json( flight.getData() ); }); app.post( "/flight/order", ( req, res ) => { if ( !req.body.boardId ) { res.status( 400 ).send( "Invalid/missing boardId" ); } if ( !req.body.order || !Array.isArray( req.body.order ) ) { res.status( 400 ).send( "Invalid/missing boardId" ); } req.body.order.forEach( ( flightId, i ) => { dataHandler.getFlight( flightId ).setOrder( i ); }); res.send( "" ); }); app.post( "/flight", ( req, res ) => { if ( !req.body.boardId ) { res.status( 400 ).send( "Invalid/missing boardId" ); } if ( !req.body.name ) { res.status( 400 ).send( "Invalid/missing flight name" ); } if ( !req.body.unitId || isNaN( req.body.unitId ) ) { res.status( 400 ).send( "Invalid/missing unitId" ); } const flight = new Flight( req.body.name, req.body.boardId, req.body.unitId ); dataHandler.addFlight( flight ); res.status( 201 ); res.json( flight.getData() ); }); app.delete( "/flight/:flightId", ( req, res ) => { const flight = dataHandler.getFlight( req.params.flightId ); if ( !flight ) { res.status( 400 ).send( `Unrecognised flight ID (given: "${req.params.flightId}")` ); } dataHandler.deleteFlight( req.params.flightId ); res.status( 204 ).send( "" ); }); module.exports = app;